Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中逐行读取txt文件_C_File_Io - Fatal编程技术网

在C中逐行读取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 {

我想逐行读取一个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++;
     }
}
我只是编辑了一下
所以我需要使用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
    }
  }