[英]getline setting failbit along with eof
我知道這種行為的起源,因為它在SO中的多個帖子中得到了很好的解釋,一些值得注意的例子是:
為什么循環條件中的iostream :: eof被認為是錯誤的?
它也包含在std::getline
標准中 :
3)如果由於某種原因沒有提取任何字符(甚至沒有丟棄的分隔符),getline設置failbit並返回。
我的問題是如何處理這種行為,你希望你的流為所有情況捕獲一個failbit
異常,除了由於到達eof
而導致的最后一行空文件。 有什么明顯的東西讓我失蹤嗎?
MWE:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
void f(const std::string & file_name, char comment) {
std::ifstream file(file_name);
file.exceptions(file.failbit);
try {
std::string line;
while (std::getline(file, line).good()) {
// empty getline sets failbit throwing an exception
if ((line[0] != comment) && (line.size() != 0)) {
std::stringstream ss(line);
// do stuff
}
}
}
catch (const std::ios_base::failure& e) {
std::cerr << "Caught an ios_base::failure.\n"
<< "Explanatory string: " << e.what() << '\n'
<< "Error code: " << e.code() << '\n';
}
}
int main() {
f("example.txt", '#');
}
其中example.txt是制表符分隔的文件,其最后一行只是\\n
char:
# This is a text file meant for testing
0 9
1 8
2 7
while(std::getline(file, line).good()){...}
復制問題。
編輯:我誤解了OP,請參閱David的上述答案。 此答案用於檢查文件是否具有終止換行符。
在while (getline)
循環結束while (getline)
,檢查file.eof()
。
假設你剛剛為文件的最后一行做了std::getline()
。
如果后面有\\n
,那么std::getline()
已經讀取了分隔符並且沒有設置eofbit
。 (在這種情況下,下一個std::getline()
將設置eofbit
。)
然而,如果它之后沒有\\n
,那么std::getline()
已經讀取了EOF並且確實設置了eofbit
。
在這兩種情況下,下一個std::getline()
將觸發failbit
並輸入您的異常處理程序。
PS:行if ((line[0] != comment) && (line.size() != 0)) {
如果line
為空則為UB。 條件的順序需要顛倒。
避免設置failbit
另一種方法是簡單地重構if
測試以檢測空行的讀取。 由於這是你在這種情況下的最后一行,你可以簡單地return
以避免拋出錯誤,例如:
std::ifstream file (file_name);
file.exceptions (file.failbit);
try {
std::string line;
while (std::getline(file, line)) {
// detect empty line and return
if (line.size() == 0)
return;
if (line[0] != comment) {
std::stringstream ss(line);
// do stuff
}
}
}
...
另一種方法是檢查eofbit
是否設置為catch
。 如果設置了eofbit
- 讀取成功完成。 例如
catch (const std::ios_base::failure& e) {
if (!file.eof())
std::cerr << "Caught an ios_base::failure.\n"
<< "Explanatory string: " << e.what() << '\n'
<< "Error code: " /* << e.code() */ << '\n';
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.