在C中逐行读取txt文件
我想逐行读取一个txt文件,每行存储在不同的变量中: 这是我想读的txt文件在C中逐行读取txt文件,c,file,io,C,File,Io,我想逐行读取一个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 {
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++;
}
}
我只是编辑了一下
所以我需要使用fgets来逐行读取,而不是fscanf(),对吗?
%s
说明符读取输入流,直到它找到一个空白字符,在您的情况下,每个地址有2个字,当您尝试读取它时,地址的第二个字就会在下一个周期读取到name
,它还存在潜在缓冲区溢出的问题
您应该使用%49[^\n]
,此说明符读取所有内容,直到找到换行符,包括空格。49
用于限制读取行的大小,以避免上述缓冲区溢出,如果您有空间容纳50个字符,则最后一个字符将用于空终止符
feof
在这种例程中也不是表示文件结束的最佳方式,更多信息请参见
在对以下工作示例的评论中,我还提到了一些其他问题:
输出:
Name: Jenny Address: Woodbridge Ave
Name: Amber Address: Exeter street
Name: Michael Address: Main Street
Name: David Address: Plainfield ave
%s
说明符读取输入流,直到它找到一个空白字符。在您的情况下,每个地址有2个字,当您尝试读取它时,它就会变得不平衡,地址的第二个字在下一个周期被读取到名称中,它还存在潜在的缓冲区溢出问题
您应该使用%49[^\n]
,此说明符读取所有内容,直到找到换行符,包括空格。49
用于限制读取行的大小,以避免上述缓冲区溢出,如果您有空间容纳50个字符,则最后一个字符将用于空终止符
feof
在这种例程中也不是表示文件结束的最佳方式,更多信息请参见
在对以下工作示例的评论中,我还提到了一些其他问题:
输出:
Name: Jenny Address: Woodbridge Ave
Name: Amber Address: Exeter street
Name: Michael Address: Main Street
Name: David Address: Plainfield ave
所以我需要使用fgets来逐行读取,而不是fscanf(),对吗
fscanf(文件“%s%s\n”,…
失败,因为%s
没有按照“Woodbridge Ave”
的需要将空格读入字符串,并且无法防止缓冲区溢出
有很多方法可以解决这个问题。fgets()
是最清楚的方法
考虑一个helper函数来读取一行并处理行输入的特性。根据需要进行调整
// return 1 on success
// return EOF on end-of-file/input error
// else return 0
int read_line(FILE *file, int sz, char *line) {
if (fgets(line, sz, file) == NULL) {
return EOF; // EOF or rare input error
}
int len = strlen(line);
if (len > 0 && line[len - 1] == '\n') {
line[--len] = '\0'; // lop off potential \n
} else if (len + 1 == sz) { // no \n read, `line` full, so look for rest of input
int ch;
int extra = 0;
while ((ch = fgetc(file)) != '\n' && ch != EOF) {
extra = 1;
}
if (extra) {
return 0; // input too long
}
}
return 1;
}
现在将文件成对地读入INFO
int read_INFO(FILE *file, int n, INFO *list) {
int i = 0;
while (i < n
&& read_line(file, sizeof list->name, list[i].name) == 1
&& read_line(file, sizeof list->add, list[i].add) == 1) {
i++;
}
return i;
}
所以我需要使用fgets来逐行读取,而不是fscanf(),对吗
fscanf(文件“%s%s\n”,…
失败,因为%s
没有按照“Woodbridge Ave”
的需要将空格读入字符串,并且无法防止缓冲区溢出
有很多方法可以解决这个问题。fgets()
是最清楚的方法
考虑一个helper函数来读取一行并处理行输入的特性。根据需要进行调整
// return 1 on success
// return EOF on end-of-file/input error
// else return 0
int read_line(FILE *file, int sz, char *line) {
if (fgets(line, sz, file) == NULL) {
return EOF; // EOF or rare input error
}
int len = strlen(line);
if (len > 0 && line[len - 1] == '\n') {
line[--len] = '\0'; // lop off potential \n
} else if (len + 1 == sz) { // no \n read, `line` full, so look for rest of input
int ch;
int extra = 0;
while ((ch = fgetc(file)) != '\n' && ch != EOF) {
extra = 1;
}
if (extra) {
return 0; // input too long
}
}
return 1;
}
现在将文件成对地读入INFO
int read_INFO(FILE *file, int n, INFO *list) {
int i = 0;
while (i < n
&& read_line(file, sizeof list->name, list[i].name) == 1
&& read_line(file, sizeof list->add, list[i].add) == 1) {
i++;
}
return i;
}
你可以告诉计算机做你想让它做的事情。现在你告诉它做不同的事情,它也在做你让它做的事情。请发布一个。特别是我们不知道你怎么称呼read
。你也不应该使用read
这个名字,因为已经有一个标准函数了,它的名字是相同的,可能是相同的将来会导致其他问题。Oh和%s%d%s
与参数不匹配。您可能需要%s%s
首先,您在(!feof(file))
时使用,并且在使用“读取”之前必须检查读取是否成功。第二,您的文件似乎没有任何内容可通过%d
读取。第三,调用未定义的行为,因为有3个输入指令,而只提供了2个指针。如果您要读取行,则不应使用scanf。您应该使用fgets
。如果您使用scanf
,则不得使用%s”
。你可以告诉计算机做你想让它做的事情。现在你告诉它做一些不同的事情,它也在做你告诉它做的事情。请发布一个。特别是我们不知道你怎么称呼read
。你也不应该使用read
这个名字,因为已经有一个标准函数了,它的名字是相同的,w这可能会在将来导致其他问题。哦和%s%d%s
与参数不匹配。您可能需要%s%s
首先,您使用时(!feof(file))
是,您必须在使用“读取”之前检查读取是否成功。第二,您的文件似乎没有任何内容可通过%d
读取。第三,调用未定义的行为,因为有3个输入指令,而只提供了2个指针。如果您要读取行,则不应使用scanf。您应该使用fgets
。如果您使用scanf
,则不得使用%s
。
int n = 20;
INFO *list = malloc(sizeof *list * n);
if (list) {
int number_read = read_INFO(file, n, list);
if (number_read > 0) {
// The happy path
}
}