我有一个名为“图形”的文本文件,其中包含“脱氧核糖核酸”字样。
当我运行此代码时,它可以工作并返回第一个字符。 “d”
int main(){
FILE *fileptr;
fileptr = fopen("graphics.txt", "r");
char name;
if(fileptr != NULL){ printf("hey \n"); }
else{ printf("Error"); }
fscanf( fileptr, "%c", &name);
printf("%c\n", name);
fclose( fileptr );
return 0;
}
当我使用fscanf
函数时,我发送的参数是FILE对象的名称,函数将读取的数据类型,以及它将存储所述数据的对象的名称,正确?另外,为什么我必须在&
但不在fscanf
中的名字前加printf
?
现在,我想让程序读取文件并抓住第一个单词并将其存储在名称中。 我知道这必须是一个字符串(一个字符数组)。 所以我做的是这样的: 我将名字命名为一个可以存储20个元素的字符数组。
char name[20];
分别将fscanf
和printf
中的参数更改为:
fscanf( fileptr, "%s", name);
printf("%s\n", name);
这样做不会产生编译器的错误,但是程序崩溃了,我不明白为什么。我让fscanf
知道我希望它读取字符串,我也让printf
知道它会输出一个字符串。我哪里做错了?我将如何完成上述任务?
答案 0 :(得分:0)
这是一个非常常见的问题。 fscanf
读取数据并将其复制到您提供的位置;首先,您需要&
,因为您提供了变量的地址(而不是值) - 这样fscanf
知道复制TO的位置。
但是你真的想要使用复制“只有我有空格的字符”的函数。这是例如fgets()
,其中包含“最大字节数”参数:
char * fgets ( char * str, int num, FILE * stream );
现在,如果您知道只为str
分配了20个字节,则可以防止读取超过20个字节并覆盖其他内存。
非常重要的概念!
其他几点。像
这样的变量声明char myString[20];
导致myString
成为指向20字节内存的指针,你可以在其中放置一个字符串(记得为终止'\ 0'!). So you can use
myString as the
char * {留出空间{1}} fscanf argument in
fgets`。但是当你尝试读取一个字符时,该字符被声明为
or
您必须“手动”创建指向内存位置的指针,这就是您最终使用char myChar;
的原因。
注意 - 如果您想要读取空格,&myChar
是更好的使用功能;但如果您不确定分配了适当的空间,那将是一个问题。正如评论中所建议的那样,你可以这样做:
fscanf
这里使用的是char myBuffer[20];
int count = fscanf(fileptr, "%19s ", myBuffer);
if(count != 1) {
printf("failed to read a string - maybe the name is too long?\n");
}
的返回值(正确转换的参数数)。你期望转换一个;如果这不起作用,它将打印消息(显然你会想要做的不仅仅是打印消息......)
答案 1 :(得分:0)
不回答你的问题但是;
为了更有效的内存使用,请使用malloc
而不是静态声明。
char *myName // declara as pointer
myName = malloc(20) // same as char[20] above on your example, but it is dynamic allocation
... // do your stuff
free(myName) // lastly free up your allocated memory for myName