c++ - file.get() 在 C++ 循环后返回随机数

标签 c++ file-io for-loop

我正在开发一个程序,将文本文件中的一系列整数读取到二维数组中。
该文件包含 40 行,每行 81 个数字,它们之间没有空格。

问题是当我在循环结束后 cout 数组时,它在 array[0][0]array[0][1] 中输出 2 个随机数 在预期输出之前。我认为这与换行符/回车符有关。循环的第一次迭代运行完美。这是代码:

#include <cstring>
#include <cstdlib>
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
  int array[9][9];

  //Open file:

  fstream ifile;

  ifile.open("numbers.txt", ios::in);
  if (ifile.fail())
    {
      cout << "Could not open numbers.txt" << endl;
      return -1;
    }

   while (!ifile.eof())
    {
      for(int i=0; i<9; i++)
      {   
    for(int j=0; j<9; j++)
    {
       int n = ifile.get();
              if(isdigit(n)) 
            {
                  array[i][j] = n - '0';
        }

          cout<<"array ["<<i<<"]["<<j<<"] is "<<array[i][j]<<endl;
      } 
      } cout<<"This is a test"<<endl;
    }

  return 0;
}

最佳答案

我完全不明白外循环的用途。首先,文件 永远不会等于 eof(),或者... eof() 是什么? 其次,如果您实际上已经编写了 while ( !file.eof() ),这可能 解释一些元素被覆盖的事实。这里将 在最后一个之后可能是一些尾随字符(至少是一个新行) 数字,因此您将再次重新进入循环。

即使你读到的字符是 不是数字。如果数据是 9 行,每行 9 位数字,你最终会得到 9 grid 中尚未初始化的单元格,以及 9 个字符 完成内部两个后还没有从文件中读取 迭代。所以你会再次进入外循环,阅读这些 人物。其中一些将是数字,所以你最终会覆盖 grid 中您已经编写的单元格——这可能是 你正在观察的效果。此外,一旦您到达文件末尾, file.get() 将开始返回 EOF——通常为 -1。那是 毫无疑问,为什么您对 '\n''\r' 的测试不起作用。

这些只是格式正确的文件的问题。为一个 格式正确的文件,只需使用 file >> nchar n; 即可 几乎工作; operator>> 跳过空格。但你仍然会进入 第二次最外层循环,因为 file.eof() 直到 输入失败。你说“我必须使用这个”,但你的代码不能 除非您更改它,否则它会工作。

就我个人而言,我喜欢具有大量错误检查功能的稳健解决方案。 ID 使用 std::getline(),我会验证每一行是否正好包含 9 数字。像这样的东西:

std::string line;
int i = 0;
while ( i < 9 && std::getline( file, line ) ) {
    if ( line.size() != 9 ) {
        throw FormatError( "wrong line length" );
    }
    for ( int j = 0; j != 9; ++ j ) {
        if ( ! isdigit( static_cast<unsigned char>( line[j] ) ) ) {
            throw FormatError( "illegal character" );
        }
        grid[i][j] = line[i] - '0';
    }
}
if ( i != 9 || std::getline( file, line ) ) {
    throw FormatError( "wrong line count" );
}

使用file.get()并不会太难,读取一个字符在 有时,但您仍想在每次阅读后检查 EOF:

for ( int i = 0; i != 9; ++ i ) {
    for ( int j = 0; j != 9; ++ j ) {
        int ch = file.get();
        if ( ch == EOF ) {
            throw FormatError( j == 0 
                                ? "line too short" 
                                : "too few lines" );
        }
        if ( !isdigit( ch ) ) {
            throw FormatError( "illegal character" );
        }
        grid[i][j] = ch - '0';
    }
    int ch = file.get();
    if ( ch != '\n' ) {
        throw FormatError( ch == EOF ? "too few lines" : "line too long" );
    }
}
if ( file.get() != EOF ) {
    throw FormatError( "too many lines" );
}

关于c++ - file.get() 在 C++ 循环后返回随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10032306/

相关文章:

c++ - 在 Qt 4.7 中,如何将弹出菜单添加到 QToolbar 按钮?

vb.net - 如何在 Visual Basic 中删除文本文件的第一行和最后一行

c++ - 你应该为 std::unordered_map 迭代器使用引用吗?

c++ - 如何在 C++ 类中使用模板化结构

c++ - 我们可以在 C 中返回一个包含数组的结构吗?

c++ - 如何查找/检测项目中的全局状态?

java - 使用java客户端实时检索jenkins的构建日志

file-io - Julia -写入文件的开头

arrays - 通过数据库中的字符使用 for 循环创建 UILabel

快速切换语句