【问题标题】:How do I read input from files?如何从文件中读取输入?
【发布时间】:2011-07-18 05:31:24
【问题描述】:

我正在尝试将文件中的输入读入数组。我似乎已经完成了必要的工作,但代码并没有按应有的方式工作。请告诉我我哪里出错了。这是我的代码:

int pb[10][10];
int i,j,n;
string ip_filename = string("pro.txt");

    ifstream fil1;

    fil1.open(ip_filename.c_str());

// to store the probabilities of the nodes
for(i=0;i<num_rows;i++)
    for(j=0;j<num_cols;j++)
    fil1 >> pb[i][j];

fil1.close();

for(i=0;i<num_rows;i++)
{
for(j=0;j<num_cols;j++)
    cout<<pb[i][j]<<" ";
cout<<endl;
}

文本文件与 cpp 文件位于同一目录中。在打印输出时,它只打印 0 而与文件中的值无关。

文件中的值存储如下

0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

num_rowsnum_cols 之前在代码中定义,两者的值都是 4。

【问题讨论】:

  • 您确定您的文件加载正确吗?
  • 代码不完整。 num_rows 和 num_cols 未定义。
  • 代码中的错误检查和/或调试将比我更好地回答您的问题...
  • @kipoltov:无法得到你的问题。我的文件和cpp文件在同一目录下。
  • @CHID:你确定 'fil1.open' 可以正常工作吗?顺便说一句,当前目录不应该是你的 cpp 文件所在的位置,而是你的 exe 文件所在的位置。

标签: c++ inputstream ifstream


【解决方案1】:

通常做这些事情最简单的方法是将数据存储在一个平面数组中(或者更好的是std::vector),并使用简单的算术来按行和列访问元素。这让事情变得简单多了。

对此的包装器可能如下所示:

template<int ColumnCount>
class MyMatrix {
public:
    template<class T>
    MyMatrix(T & begin, T & end) : data(begin, end) {}

    int getItem(int i, int j) const {
        return data[i*ColumnCount+j];
    }
private:
    std::vector<int> data;
};

然后你可以像这样读取数据:

std::ifstream file1("pro.txt");
std::istream_iterator<int> begin(file1);
std::istream_iterator<int> end;

MyMatrix<4> m(begin, end);

【讨论】:

    【解决方案2】:

    使用 fstream 时,为了进行健壮的编码,最好在 open() 之后使用 is_open() 并在 operator 此外,更喜欢

    while(getline(fil1, lineString))
    {
      ...;
    }
    

    这样您就可以检查您正在阅读的哪一行以及出了什么问题。

    检查愉快...

    【讨论】:

      【解决方案3】:

      正如我所见,您想从文件中加载矩阵。在文件中,您的值存储为以空格分隔的字符串。所以你应该加载你的文件,逐行读取文件,将你的字符串分成一个字符串数组,然后将你的值从字符串转换为 int 并将它们存储到你的矩阵中。

      【讨论】:

      • 哦,是吗..我试图直接做。可能是你我不明白的......谢谢你安德雷尔
      • ifstream 为您进行转换。它将读取空间并尝试将读取的内容转换为要存储的变量的类型。
      • @dave:如果是这样,我的文件遵循 ifstream 的格式。但是没有输出.. ifstream 遇到 \n 字符时会做什么
      • @CHID ifstream 将跳过所有空格,包括 \n 字符。如果所有 16 个数字都在一行上,该代码也可以正常工作。请参阅我的答案,我按原样尝试了您的代码,它对我来说很好。
      【解决方案4】:

      这段代码对我来说非常好,pro.txt 格式如你所见:

      #include <iostream>
      #include <fstream>
      #include <string>
      
      using namespace std;
      
      int main()
      {
          int num_rows = 4;
          int num_cols = 4;
          int pb[10][10];
          int i,j,n;
          string ip_filename = string("pro.txt");
      
          ifstream fil1;
      
          fil1.open(ip_filename.c_str());
      
          // to store the probabilities of the nodes
          for(i=0;i<num_rows;i++)
              for(j=0;j<num_cols;j++)
                  fil1 >> pb[i][j];
      
          fil1.close();
      
          for(i=0;i<num_rows;i++)
          {
              for(j=0;j<num_cols;j++)
                  cout<<pb[i][j]<<" ";
              cout<<endl;
          }
      
      }
      

      我的建议是确保 pro.txt 与您的 .exe 文件位于同一目录中。如果您使用 IDE 构建此代码,则它可能与您的 .cpp 文件不同。

      【讨论】:

      • 哇。 gr8 建议戴夫。但现在我得到的是垃圾值而不是 int 值。代码中有问题吗?
      • @CHID 我构建并运行了发布的内容,并且运行良好。尝试查看此代码和您的代码之间可能存在哪些差异。我唯一做的就是将您发布的代码包装在main() 函数中并定义num_rowsnum_cols
      【解决方案5】:

      每次操作后流的状态如何?你不应该 无需验证即可阅读。你不应该在没有阅读的情况下阅读 验证打开是否有效:

      ifstream fill( ip_filename.c_str() );
      if ( !fill ) {
          //  error handling, open failed...
      }
      

      之后,我会同意逐行阅读的建议:

      int row = 0;
      string line;
      while ( getline( fill, line ) && row < size( pb ) ) {
          istringstream sLine( line );
          int col = 0;
          int tmp ;
          while ( sLine >> tmp && col < size( pb[ row ] )) {
              pb[row][col] = tmp;
              ++ col;
          }
          if ( col != size( pb[ row ] ) ) {
              //  Input error, too few entries
          } else if ( sLine >> ws && sLine.get() != EOF ) {
              //  Input error, garbage at end of line <row>
          }
          ++ row;
      }
      if ( row != size( pb ) ) {
          //  Input error, garbage at end of file
      }
      

      或者,您可以根据动态决定尺寸 输入:

      std::vector<std::vector<int> > pb;
      ifstream fill( ip_filename.c_str() );
      if ( !fill ) {
          //  error handling, open failed...
      }
      string line;
      while ( getline( fill, line ) ) {
          std::vector<int> tmp1;
          istringstream sLine( line );
          int tmp2;
          while ( sLine >> tmp2 ) {
              tmp1.back().push_back( tmp2 );
          }
          if ( sLine >> ws && ! sLine.eof() ) {
              //  input error: non-numeric data in line
          } else if ( ! pb.empty() && tmp1.size() != pb.back().size() ) {
              //  input error : inconsistent number of columns.
          }
      }
      //  Check here if square matrix required.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多