C ++ getline和gcount

时间:2011-10-19 00:12:55

标签: c++

假设我有一个std::istream指向以下内容(换行符是'\n'个字符):

12345678
9

并运行以下代码:

std::istream & is = ...
char buff[9];
is.getline(buff, 9);
int n = is.gcount();

现在n == 8strcmp(buff, "12345678") == 0。问题是,我怎么知道我读了整条线而不是一些线?

如果蒸汽代替以下内容:

123456789
0

并执行相同的代码,我仍然在同一行。我如何区分这两种情况?

3 个答案:

答案 0 :(得分:3)

使用std::string和免费std::getline功能:

#include <istream>
#include <string>

// ...

std::istream & is = ...;
std::string line;

while (std::getline(is, line))
{
  // process line
}

答案 1 :(得分:1)

答案的关键在于你的问题

is.getline(buff, 9);
int n = is.gcount();
Now n == 8

根据reference for getline,它会提取最多n - 1个字符 - 在您的情况下,最多8个。这有点误导,因为如果第n个字符是分隔符,它也会被提取(但不被复制到缓冲区)。更重要的是,如果您在到达n字符之前没有达到分隔符,则此部分是相关的:

If the function stops reading because this size (n) is reached,
the failbit internal flag is set

因此,简而言之,如果设置了失败位,您仍然在同一行(并且您必须清除状态才能继续处理istream)。有时,eof也会设置失败位。所以你可能想检查一下状态是否为failbit且只有failbit:

if ( is.rdstate() == std::ios::failbit ) {
  std::cout << "Filled the buffer, but did NOT finish the line\n";
  is.clear();
}

答案 2 :(得分:0)

阅读下一个角色。如果是换行符,则表示您已阅读该行的所有数据。

顺便说一下,流行的用法是将整行(直到换行符)读入std::string,然后处理字符串。