从文件中读入 char 到 struct

Reading in char from file into 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);
}

样本修复

#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;
}

由于这是一项 class 作业,我想先说明处理这些类型作业的一个好方法是将其分解为多个任务,然后一个一个地执行它们,最后连接它们。在这种情况下,任务可能类似于:

  • 将第一行解析为(包含一个)字符数组的结构。
  • 将数字解析成一个int变量
  • 像处理第一行一样分析文件中剩余的每一行
  • 根据文件中的其他行测试第一行(数字除外)

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

现在,让我们看一下代码。我不会在这里给你程序,但我会找出我在其中看到的问题。

让我们从主要方法开始:

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

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

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

fclose(input);

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

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

完成后,您需要注意的是,如果您要传递或 returning 数组或指针 to/from 函数,您将需要查找 mallocfree 函数,您可能还没有涉及这些函数。这可能是 C 语言中较为复杂的部分之一,因此您可能希望将其留到最后。

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

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

希望对您有所帮助!

一个简单的修复可能是:

#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 函数中的代码[长度],您必须传递它的地址,这就是我以这种方式调用 mkaeArray 函数的原因:makeArray(input,&first);.