从文件中读取char到struct

时间:2015-04-16 17:34:11

标签: c file-io struct

对于我的作业,我必须阅读包含不同行数的文本文件。它们遵循以下格式:

AACTGGTGCAGATACTGTTGA
3
AACTGGTGCAGATACTGCAGA
CAGTTTAGAG
CATCATCATCATCATCATCAT

第一行是原始行,我将测试以下的行,第二行给出剩余行数。

我在尝试将这些保存到结构体时遇到了麻烦,甚至无法获得保存的第一行。我尝试使用带有数组的void函数,它似乎工作,但似乎无法将其转移到结构。

到目前为止,这是我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define LENGTH 25
struct dna {
    char code[LENGTH];
};
int main(){
    char filename[] = "input1.txt";
    FILE *input = fopen("input1.txt","r");

    char firstDna[LENGTH]="";

    struct dna first;
    struct dna first.code[]= "";

    makeArray(input,first);

//  printf("%s",filename);


    system("pause");
    return 0;
}
void makeArray(FILE *input,struct dna first){
    int i=-1;
    //nested for loops to initialze array
    //from file
    while(i != '\n'){
       fscanf(input,"%c",first[i].code); 
       printf("%c", first[i].code);
       i++;
    }//closing file
    fclose(input);
}

3 个答案:

答案 0 :(得分:1)

要修复的示例

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define LENGTH 25

struct dna {
    char code[LENGTH];
};

struct dna *makeArray(FILE *input, int *n);//n : output, number of elements

int main(void){
    char filename[] = "input1.txt";
    FILE *input = fopen(filename,"r");

    struct dna first = { "" };
    fscanf(input, "%24s", first.code);//read first line
    printf("1st : %s\n", first.code);

    int i, size;
    struct dna *data = makeArray(input, &size);//this does close file

    for(i = 0; i < size; ++i){
        printf("%3d : %s\n", i+1, data[i].code);
    }
    free(data);//release data

    system("pause");
    return 0;
}

struct dna *makeArray(FILE *input, int *n){//n : output, number of elements
    int i;

    fscanf(input, "%d", n);//read "number of remaining lines"

    struct dna *arr = calloc(*n, sizeof(struct dna));//like as struct dna arr[n] = {{0}};

    for(i = 0; i < *n; ++i){
        fscanf(input, "%24s", arr[i].code);
    }
    fclose(input);

    return arr;
}

答案 1 :(得分:1)

因为这是一个类赋值,所以我想通过说解决这些类型的赋值的一个好方法是将其分解为任务,然后逐个实现它们并最终连接它们。在这种情况下,任务可能类似于:

  • 将第一行解析为(包含a)char数组。
  • 将数字解析为int变量
  • 解析文件中的每个剩余行,就像使用第一行
  • 一样
  • 测试第一行与文件中的其他行(数字除外)

您还在评论中提到该结构是为了额外的功劳。出于这个原因,我建议首先使用char数组实现它,然后在基本版本工作后将其重构为结构。这样你就可以依赖以防万一。这种发展方式在这一点似乎是不必要的,但对于更大更复杂的项目来说,它变得更加重要,因此尽可能早地进入是一个非常好的习惯。

现在,让我们看看代码。我不会在这里给你这个程序,但是我要确定我在其中看到的问题。

让我们从主要方法开始:

char filename[] = "input1.txt";
FILE *input = fopen("input1.txt","r");

这将打开您正在阅读的文件。你正确打开它,但第一行在这种情况下是不必要的,因为你从来没有在任何地方实际使用文件名变量。

您还可以使用以下行正确关闭makeArray函数末尾的文件:

fclose(input);

哪个有效。但是,如果在调用main函数后将其放在makeArray方法中,那么它可能会更好。如果可能的话,在同一个函数中打开和关闭文件总是一个好主意,因为这意味着你总是知道你不会忘记关闭文件而不必查看整个程序。同样,在一个小项目中并不是真正的问题,而是一个良好的习惯。另一个解决方案是将fopenfclose函数放在makeArray函数中,因此main不必知道它们,然后只发送{{1包含char的文件路径的数组,而不是makeArray

我看到的下一个问题是如何将参数传递给FILE*函数。首先,尝试将所有内容放在main方法中,而不是使用单独的函数。使用函数是一种很好的做法,但这样做只是为了让事情有效。

一旦完成,你需要注意的是,如果你传递或返回数组或指向函数的指针,你需要查找makeArraymalloc函数,你可能还没有涉及。这可能是C中比较复杂的部分之一,因此您可能希望将其保存到最后。

其他一些事情。我不会详细介绍这些,但尝试获取概念,而不仅仅是复制粘贴:

  • free应该是struct dna first.code[]= "";。在C中使用first.code[0] = \0;来终止字符串,因此这将使字符串为空。
  • \0传递给%c会读取一个字符(您也可以使用fscanf)。在这种情况下,使用fgetc可能会更容易,它会将一个单词作为字符串返回。
  • 假设您确实使用了%s,您可能需要在循环之前调用它两次 - 一次获取第一个DNA序列,另一次获取其他DNA序列的数量(数量)迭代)。
  • 然后,循环的每次迭代将针对文件中的下一个DNA序列测试原始DNA序列。

我希望有所帮助!

答案 2 :(得分:1)

一个简单的修复可能是:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define LENGTH 25

struct dna {
    char code[LENGTH];
};

void makeArray(FILE *input,struct dna *first){
    int i=0;
    fscanf(input,"%c",&first->code[i]);
    printf("%c",first->code[i]);
    while(first->code[i] != '\n' && i < LENGTH){
        i++;
        fscanf(input,"%c",&first->code[i]);
        printf("%c",first->code[i]);
    }
}

int main() {
    struct dna first;
    char filename[] = "input1.txt";
    FILE *input     = fopen(filename,"r");
    makeArray(input,&first);
    fclose(input);
    printf("%s",first.code);
    return 0;
}

PS:我试图不改变您的原始代码 为了更改makeArray函数中的代码[Length],你必须传递它的地址,这就是我用这种方式调用mkaeArray函数的原因:makeArray(input,&first);