C++ tellg()不能与getline()一起使用?

use*_*171 5 c++ getline ifstream

我知道标题听起来很疯狂,但我现在正在亲身体验这一点,我想不出有什么原因导致失败.

我正在使用getline()阅读文件

在阅读结束时,我打电话给tellg().但是,此调用始终失败(返回值为-1).

这是一个已知问题,tellg()不能与getline()一起使用,还是我做错了什么?

基本上,我使用的代码非常简单

while(getline(file,line))
{
//tokenize and do other things
}
cout<<file.tellg()<<endl;
Run Code Online (Sandbox Code Playgroud)

有问题的文件是普通磁盘上的一个简单的txt文件,我尝试了一个有和没有CRLF的文件,它没有任何区别.

编辑:其他信息

gcc/g ++ 4.1.2,Linux(RHEL 5)

编辑2:根据这个帖子:http: //www.cplusplus.com/forum/beginner/3599/#msg15540由于某种gcc错误,不可能将getg与getline一起使用.实际情况如此吗?(你在网上看到的并不总是如此= P)

pax*_*blo 7

tellg()函数的工作原理是尝试构造一个sentry对象,然后failbit在返回一个正确的值之前检查它.如果failbit设置,则返回-1.详细信息可以在这里找到,或者,如果您更喜欢更官方的来源并且不介意干读,那么ISO C++标准(27.6.1.3/36a-37适用于C++ 03,27.7.2.3/39-40适用于C++ 11).

哨兵的构造首先检查任何错误标志(如eofbit),如果设置,则设置failbit和返回.有关详细信息,请参见此处(C++ 03 27.6.1.1.2,C++ 11 27.7.2.1.3),

因此tellg(),在设置文件结束标志之后将失败.您正在读取行直到getline返回false 这一事实意味着eofbit正在设置流,因此您已到达文件的末尾.

您可以使用以下程序查看行为:

#include <iostream>
#include <iomanip>

int main (void) {
    std::string line;
    while (std::getline (std::cin, line)) {
        if (line.length() > 20)
            line = line.substr(0,17) + "...";
        std::cout << "tellg() returned "
            << std::setw(5) << std::cin.tellg()
            << " after " << line << "\n";
    }
    //std::cin.clear();
    std::cout << "tellg() returns: "
        << std::cin.tellg() << '\n';
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当您运行它并提供文件本身作为输入时,您会看到:

tellg() returned    20 after #include <iostream>
tellg() returned    39 after #include <iomanip>
tellg() returned    40 after 
tellg() returned    58 after int main (void) {
tellg() returned    80 after     std::string l...
tellg() returned   124 after     while (std::g...
tellg() returned   156 after         if (line....
tellg() returned   202 after             line ...
tellg() returned   243 after         std::cout...
tellg() returned   291 after             << st...
tellg() returned   333 after             << " ...
tellg() returned   339 after     }
tellg() returned   363 after     //std::cin.cl...
tellg() returned   400 after     std::cout << ...
tellg() returned   437 after         << std::c...
tellg() returned   451 after     return 0;
tellg() returned   453 after }
tellg() returned   454 after 
tellg() returns: -1
Run Code Online (Sandbox Code Playgroud)

如果取消注释该代码中清除错误状态变量的行,它将起作用:

tellg() returned    20 after #include <iostream>
tellg() returned    39 after #include <iomanip>
tellg() returned    40 after 
tellg() returned    58 after int main (void) {
tellg() returned    80 after     std::string l...
tellg() returned   124 after     while (std::g...
tellg() returned   156 after         if (line....
tellg() returned   202 after             line ...
tellg() returned   243 after         std::cout...
tellg() returned   291 after             << st...
tellg() returned   333 after             << " ...
tellg() returned   339 after     }
tellg() returned   361 after     std::cin.clea...
tellg() returned   398 after     std::cout << ...
tellg() returned   435 after         << std::c...
tellg() returned   449 after     return 0;
tellg() returned   451 after }
tellg() returned   452 after 
tellg() returns: 452
Run Code Online (Sandbox Code Playgroud)

而且,顺便说一句,看起来你所指的那个bug可能就是这个(它有点不清楚,因为你链接到的帖子遗憾地遗漏了任何细节 - 如果海报打扰支持他的断言会更好它是一个已知的bug,例如,链接到它).

如果是这样的话,你应该注意的第一件事就是它已经修复了十多年,所以,除非你使用的是绝对古老的 gcc,否则它现在不会成为一个问题.