【问题标题】:reading until the end of file in C++在 C++ 中读取直到文件末尾
【发布时间】:2012-11-24 18:30:48
【问题描述】:

我正在尝试读取一个电话簿应用程序的文件末尾,该应用程序从 C 转换为 C++。当我从文件中打印结果时,我得到了这个:

johnny smith
(Home)3
(Cell)4
x☺> x☺>
(Home)4
(Cell)4

应该打印出来:

johnny smith
(Home)3
(Cell)4

现在我正在使用while(!infile.eof()),我认为这是一种糟糕的做法,但是当我使用infile.getline() 时,我会重复名字和姓氏,并且格式都被抬高了。无论如何(或另一种方式)来摆脱输入末尾的垃圾或另一种读取 C++ 文件末尾的方式来解决这个问题。我一直在阅读不同的解决方案,但很多网站似乎都同意fgets,这是我在原始 C 版本中所拥有的,但显然fgets 不适用于ifstream是我正在使用的。这是代码:

void contacts:: readfile(contacts*friends ,int* counter, int i,char buffer[],char    user_entry3[])
{
   ifstream read;
   read.open(user_entry3,ios::in);
   int len;
   contacts temp;
   *counter=0;
   i=0; 

     while (!read.eof()) { 
       temp.First_Name=(char*)malloc(36); 
       temp.Last_Name=(char*)malloc(36); 

       read>>temp.First_Name>>temp.Last_Name;

       read>>buffer;
       len=strlen(buffer);
       if(buffer[len-1]=='\n')
          buffer[len-1]='\0';

       temp.home=(char*)malloc(20); 
       strcpy(temp.home, buffer);

       read>>buffer;
       len=strlen(buffer);
       if(buffer[len-1]=='\n')
       buffer[len-1]='\0';


       temp.cell=(char*)malloc(20); 
       strcpy(temp.cell, buffer); 

      friends[i].First_Name=(char*)malloc(MAXNAME);
      friends[i].Last_Name=(char*)malloc(MAXNAME);
      friends[i].home=(char*)malloc(MAXPHONE);
      friends[i].cell=(char*)malloc(MAXPHONE);


  //adds file content to the structure
      strcpy(friends[*counter].First_Name,temp.First_Name);
      strcpy(friends[*counter].Last_Name,temp.Last_Name);
      strcpy(friends[*counter].home,temp.home);
      strcpy(friends[*counter].cell,temp.cell);


     (*counter)++;
     i++; 

   }
   //closes file and frees memory
    read.close();
    free(temp.Last_Name);
    free(temp.First_Name);
    free(temp.home);
    free(temp.cell);
}

【问题讨论】:

  • 你能给我们文件的内容吗?
  • 文件就是johnny smith下一行3下一行4<Home><Cell> 在文件被读入类后打印出来,这只是我格式化它的方式。
  • 这个:while (!read.eof()) 总是错的。总是。如果发生错误怎么办?你如何抓住它并停止阅读?

标签: c++ file


【解决方案1】:

不要使用eof() 来确定您是否到达文件末尾。相反,请阅读您要阅读的内容,然后然后检查您是否成功读取了数据。如果读取失败,您可以使用eof() 确定错误是否已到达文件末尾,然后再生成有关格式错误的错误报告。

既然你提到你读到使用!infile.eof() 是一种很好的做法:你能指出这些错误信息的来源吗?此信息需要更正。

【讨论】:

  • 我的帖子说我读到它是糟糕的做法,而不是好的做法。
  • 对不起,我的阅读不佳。但是,if (infile.getline(buffer, n)) { ... } 应该可以正常工作(尽管我建议使用 std::getline(in, str)std::string
  • ninfile.getlinestatement 中代表什么。原谅我是菜鸟哈哈。
  • n 是您可以在buffer 中存储的char 的最大数量。假设 buffer 被声明为 char buffer[17]; 它是 17sizeof(buffer)`。
  • 好的,这就是我的想法,这也是我在使用 getline 时一直在尝试的。我的问题是,当我使用 getline 时,我的输出看起来像 3 4 next line<Home> johnny smith next line <Cell>johnny smith。它不仅两次打印出名称,而且显然提升了格式。
【解决方案2】:
  1. 不要使用!eof()。它检查 last 读取失败是否是由于到达文件末尾。它不能预测未来。

  2. 不要在 C++ 中使用 malloc。如果这样做,请检查返回值是否有错误!

  3. 不要将operator>> 用于char *。没有大小检查,所以只是要求缓冲区溢出。

  4. '\n' 检查缓冲区没有用。 operator>> 表示字符串在空格处停止。

  5. 你盲目地将未知长度的字符串 strcpy 写入大小为 20 的 temp.home。这是另一个缓冲区溢出。

  6. ...我有点停止阅读那里。如果您想从文件中读取内容但在 eof/error 时停止,您可以执行以下操作:

.

string a, b, c;
while (true) {
    if (!(in >> a)) break;
    if (!(in >> b)) break;
    if (!(in >> c)) break;
    do_stuff_with(a, b, c);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    相关资源
    最近更新 更多