我想逐行读取txt文件,并且每行都存储在不同的变量中:这是我要读取的txt文件
Jenny
Woodbridge Ave
Amber
Exeter street
Michael
Main Street
David
Plainfield ave
我确实喜欢
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
typedef struct info
{
char name[20];
char add[50];
}INFO;
int main(void){
const char *fileName = "test.txt";
FILE *file = fopen(fileName, "r");
INFO* list = (INFO*)malloc(20*sizeof(INFO));
readFromFile(file,list);
fclose(file);
free(list);
return 0;
}
void readFromFile(FILE *file,INFO* list){
int i = 0;
while(!feof(file)){
fscanf(file,"%s %s\n ",(list+i)->name,(list+i)->adds);
i++;
}
}
但我得到
Name: Jenny
Addr: Woodbridge
------------------------------
Name: Ave
Addr: Amber
------------------------------
Name: Exeter
Addr: street
------------------------------
Name: Michael
Addr: Main
------------------------------
Name: Street
Addr: David
------------------------------
Name: Plainfield
Addr: ave
我只做了一点编辑,所以我需要使用fgets逐行读取而不是fscanf()对吗?
%s
说明符读取输入流,直到找到一个空白字符为止(在您的情况下,因为每个地址有2个单词,一旦您尝试读取它,它就会变得不平衡,下一个循环将读取地址的第二个单词name
,它还有一个潜在的缓冲区溢出问题。
您应该使用%49[^\n]
,该说明符将读取所有内容,直到找到换行符,包括空格。的49
目的是限制读取行的大小,以避免提及的缓冲区溢出,如果您有足够的空间容纳50
字符,则最后一个字符将用于空终止符。
feof
在这种例行程序中也不是发出信号结束信号的最佳方式,更多信息请参见为什么“ while(!feof(file))”总是错误的?。
我在以下工作示例的注释中还解决了其他一些问题:
int main()
{
//casting malloc may make you program fail, it hides the lack of #include <stdlib.h>
INFO* list = malloc(20 * sizeof *list); //using the the dereferenced variable
//is safer regarding future code refactoring
const char *fileName = "test.txt";
FILE *f = fopen(fileName, "r"); //dont forget to verify the return of fopen
int i = read(f, list);
for (int j = 0; j < i; j++) //test print
{
printf("Name: %s Address: %s\n", list[j].name, list[j].add);
}
}
int read(FILE *file, INFO *list)
{
int i = 0;
//use scanf as stop condition, [] notation is easier to read
//limiting the size in scanf specifiers avoids buffer overflow
while (fscanf(file, "%19s %49[^\n]", list[i].name, list[i].add) == 2)
{
i++;
}
//return i so that you know how many structs were read
return i;
}
输出:
Name: Jenny Address: Woodbridge Ave
Name: Amber Address: Exeter street
Name: Michael Address: Main Street
Name: David Address: Plainfield ave
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句