首页 > 解决方案 > 提取运算符在 istringstream 上达到 EOF,使用 int/char/string 改变行为

问题描述

所以我在 C++ 中做一些简单的文件 I/O,我注意到了这种行为,不确定我是否忘记了一些关于提取运算符和字符的内容

注意Unix中的文件格式。

ifstream infile("test.txt");
string line;
while(getline(infile, line)){
  istringstream iss(line);
  
  **<type>** a;
  
  for(...){
     iss >> a;
  }

  if(iss.eof()) 
    cout << "FAIL" << endl;

}

假设输入文件 test.txt 看起来像这样,并且 a 的 <type> 是 int

$ 是换行符(:set line)

100 100 100$
100 100 100$

我注意到的是,在读取第一行之后,EOF 设置为 true;

如果输入文件是这样,并且a的<type>是char:

a b c$
a b c$

然后代码的行为完全符合预期。

根据我对文件 I/O 和提取运算符的了解,前导空格被忽略,并且在从输入字符串流 iss 中取出输入后,回车符落在字符上。所以在这两种情况下,在每个字符串流的末尾,马车都会落在换行符上,它不应该是 EOF。

将 a 的 <type> 更改为字符串的失败与 <type> = int 类似

BTW failbit 未设置,
最后:good = 0
fail = 0
eof = 1

标签: c++file-ioeofistringstream

解决方案


getline已提取并丢弃换行符,因此line包含100 100 100,而不是100 100 100$,其中$代表换行符。line这意味着使用 a读取所有三个令牌,stringstream操作>>员可能会到达 EOF 并产生 FAIL 消息。

iss >> a;when ais an intor astring将跳过所有前面的空白,然后继续提取,直到它到达一个不可能是 an 的一部分的字符,int或者是空白或者是流的结尾。在流的第三个>>,流的末尾停止提取并设置流的 EOF 标志。

iss >> a;when ais anchar将跳过所有前面的空格,然后只提取一个字符。在这种情况下,第三个>>将提取最后一个字符并在看到流的结尾之前停止并且不设置 EOF 标志。


推荐阅读