从文件中读入 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
方法中,可能会更好。如果可能的话,在同一个函数中打开和关闭文件总是一个好主意,因为这意味着您将始终知道您没有忘记关闭文件,而不必查看整个程序。同样,这在小项目中并不是一个真正的问题,而是一个需要养成的好习惯。另一种解决方案是将 fopen
和 fclose
函数放在 makeArray
函数中,因此 main
不必知道它们,然后只需发送 char
包含文件路径的数组 makeArray
而不是 FILE*
.
我看到的下一个问题是如何将参数传递给 makeArray
函数。首先,不要使用单独的函数,而是尝试将所有内容放在 main 方法中。使用函数是一种很好的做法,但这样做只是为了让某些东西起作用。
完成后,您需要注意的是,如果您要传递或 returning 数组或指针 to/from 函数,您将需要查找 malloc
和 free
函数,您可能还没有涉及这些函数。这可能是 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);
.
对于我的作业,我必须读入一个包含不同行数的文本文件。它们遵循以下格式:
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
方法中,可能会更好。如果可能的话,在同一个函数中打开和关闭文件总是一个好主意,因为这意味着您将始终知道您没有忘记关闭文件,而不必查看整个程序。同样,这在小项目中并不是一个真正的问题,而是一个需要养成的好习惯。另一种解决方案是将 fopen
和 fclose
函数放在 makeArray
函数中,因此 main
不必知道它们,然后只需发送 char
包含文件路径的数组 makeArray
而不是 FILE*
.
我看到的下一个问题是如何将参数传递给 makeArray
函数。首先,不要使用单独的函数,而是尝试将所有内容放在 main 方法中。使用函数是一种很好的做法,但这样做只是为了让某些东西起作用。
完成后,您需要注意的是,如果您要传递或 returning 数组或指针 to/from 函数,您将需要查找 malloc
和 free
函数,您可能还没有涉及这些函数。这可能是 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);
.