Функция tellg()
работает, пытаясь создать объект часового, а затем проверяя 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;
}
Когда вы запустите это и предоставите сам файл в качестве входных данных, вы увидите:
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
Если вы раскомментируете строку в этом коде, которая очищает переменные состояния ошибки, это сработает:
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
Кроме того, похоже, что ошибка, о которой вы говорите, может быть этим один (это немного неясно, поскольку в сообщении, на которое вы ссылаетесь, к сожалению, отсутствуют какие-либо детали - было бы лучше, если бы автор потрудился поддержать свое утверждение о том, что это известная ошибка, например, ссылка на него).
Если это так, первое замечание, которое вы должны заметить, это то, что оно было исправлено более десяти лет назад, поэтому, если вы не используете абсолютно древний gcc
, он не будет быть проблемой сейчас.
person
paxdiablo
schedule
26.06.2013
file.clear()
передfile.tellg()
, чтобы очиститьfailbit
. - person Vaughn Cato   schedule 26.06.2013