无论如何将文件重置为初始状态?

时间:2012-03-26 19:36:32

标签: c++ stream fileinputstream file-io

我正在尝试用C ++中的文本文件输入数据。 文本文件采用以下格式:

4 15
3 516
25 52 etc.

每行包含两个整数。我不知道文件中的行数,所以我可以绑定足够的内存,这就是我解决这个问题的方法:

ifstream filein;
filein.open("text.txt",ios::in);
int count=0;

while (!filein.eof())
    {
        count++;
        filein>>temporary;
    }
count=count/2; // This is the number of lines in the text file.

我的问题是我找不到重置的方法

  

FILEIN

进入初始状态(对于文件的开始,所以我实际上可以输入数据),而不是关闭输入流并再次打开它。还有其他办法吗?

3 个答案:

答案 0 :(得分:5)

我没有回答你问的问题,而是回答你没有提出的问题,即:

  

问:如果我不知道有多少行,我怎么能读入文件的所有行?

答:使用std::vector<>

如果您想阅读所有数字,无论是否配对:

// all code fragments untested. typos are possible
int i;
std::vector<int> all_of_the_values;
while(filein >> i)
    all_of_the_values.push_back(i);

如果您想读取所有数字,请将交替数字放入不同的数据结构中:

int i, j;
std::vector<int> first_values;
std::vector<int> second_values;
while(filein >> i >> j) {
    first_values.push_back(i);
    second_values.push_back(j);

如果您想读入所有数字,请将它们存储在某种数据结构中:

int i, j;
struct S {int i; int j;};
std::vector<S> values;
while(filein >> i >> j) {
    S s = {i, j};
    values.push_back(s);
}

最后,如果你想一次读取一行文件,保留每行的前两个数字,丢弃每行的剩余部分,并存储用户定义的数据结构:

std::vector<MyClass> v;
std::string sline;
while(std::getline(filein, sline)) {
  std::istringstream isline(sline);
  int i, j;
  if(isline >> i >> j) {
    values.push_back(MyClass(i, j));
  }
}

<小时/> 除了:永远不要在循环条件中使用eof()good()。这样做几乎总会产生错误的代码,就像你的情况一样。而是更喜欢在条件中调用输入函数,如上所述。

答案 1 :(得分:2)

该功能是:filein.seekg (0, ios::beg);

这是Reference

如果你这样做,你还应该使用filein.clear()重置文件中的eof位。

当然,如果你想要最好的方法来解决你最终想做的事情,Robᵩ的答案要好得多,尽管更多。

答案 2 :(得分:2)

我认为@Robᵩ几乎是正确的想法 - 而不是只读取所有数据来计算行数,然后再读取整个文件以实际读取数据,使用类似{{1}的内容}(或std::vector)将在您阅读数据时根据需要进行扩展。

然而,在典型情况下,一行上的两个数字将彼此相关,并且您通常希望以直接显示该关联的方式存储它们。例如,它们可能是点的X和Y坐标,在这种情况下,您想要读取点:

std::deque

稍微不同的说明:即使您决定要使用显式循环,不要使用class point { int x, y; }; std::istream &operator>>(std::istream &is, point &p) { return is >> p.x >> p.y; } std::ifstream in("myfile.txt"); // create the vector from the data in the file: std::vector<point> points((std::istream_iterator<point>(in)), std::istream_iterator<point>()); 来执行此操作 - 这几乎可以保证失败。你想检查阅读数据是否成功,所以(例如)使用上面的while (!whatever.eof())类,你可以使用类似的东西:

point