![](/img/trans.png)
[英]std::getline doesn't skip empty lines when reading from ifstream
[英]extraneous empty lines when reading from an ifstream
在我的程序中,我已將標准輸出重定向到打印到文件“ console.txt”。 函數將如下所示寫入該文件:
void printToConsole(const std::string& text, const TCODColor& fc, const TCODColor& bc)
{
// write the string
cout << text << "@";
// write the two color values
cout << static_cast<int>(fc.r) << " "
<< static_cast<int>(fc.g) << " "
<< static_cast<int>(fc.b) << " "
<< static_cast<int>(bc.r) << " "
<< static_cast<int>(bc.g) << " "
<< static_cast<int>(bc.b) << " " << endl;
}
我有一個從該文件讀取的函數,如下所示:
void Console::readLogFile()
{
ifstream log("console.txt", ifstream::in);
if(!log.is_open())
{
cerr << "ERROR: console.txt not found!" << endl;
return;
}
// read new input into the stack
char str[256];
while(!log.eof())
{
log.getline(str, 256);
cerr << "str: " << str << endl;
stk.push(static_cast<string>(str));
// stk is a std::stack<std::string> member of the class this function
// belongs to.
}
cerr << endl;
/* Do some stuff with str and stk here */
log.close();
clearLogFile();
}
void Console::clearLogFile()
{
FILE* log;
log = fopen("console.txt", "w");
fclose(log);
}
通常,在readLogFile
時console.txt為空。 我希望在那種情況下while(!log.eof())
循環永遠不會執行,但是確實可以。 文件中總是至少有一個多余的空白行,有時是兩個,並且從文件中讀取輸入時,輸入行夾在兩個空白行之間。 幾次調用此函數后, while(!log.eof())
循環進入無限循環,從文件中拉出空白行。 該程序的典型運行過程如下所示:
str:
str: Player moved.@191 191 191 0 0 0
str:
str:
str: Player moved.@191 191 191 0 0 0
str:
str: // there should be a 'Player moved.' line in here
str:
str: // here as well
str:
str: // also here
str:
str:
str: Player moved.@191 191 191 0 0 0
str:
str:
str:
str:
str:
str:
str:
(onto infinite loop)
誰能看到我在這里做錯了什么?
編輯:如Amardeep所建議,我將while(!log.eof())
循環更改為do{...}while(!log.fail);
環。 這解決了無限循環問題,但沒有解決多余的問題。 該程序的行為與以前相同,除了它曾經進入無限循環的地方外,它現在只讀取應讀取輸入的空白行,如下所示:
str:
str:
str:
str:
(etc.)
嘗試讀取之前,不會設置eof()狀態。 您應該更改讀取循環以執行getline(),然后檢查fail()狀態,而不要依賴eof(),因為eof()不能解決嘗試讀取文件時可能出錯的問題。
用於讀取文件的標准反模式。
while(!log.eof())
{
log.getline(str, 256);
cerr << "str: " << str << endl;
stk.push(static_cast<string>(str));
// stk is a std::stack<std::string> member of the class this function
// belongs to.
}
嘗試這個:
while(log.getline(str, 256))
{
cerr << "str: " << str << endl;
stk.push(string(str));
}
之所以可行,是因為getline()方法返回對該流的引用。
當在布爾上下文中使用流時,它將轉換為布爾值(不是真正的學徒,而是初學者)。 如果流在讀取后仍處於良好狀態(即讀取有效),則將其轉換為true。 如果流處於不良狀態(即讀取失敗),則將其轉換為false。 因此,如果讀取成功,則進入循環。 如果讀取失敗(因為可能讀取了EOL),則不會進入循環。
請注意,您的版本失敗了,因為在讀取(getline())之后未測試eof()。 之所以這樣,是因為最后一次讀操作會讀取直到EOF的所有字符。 但這意味着未設置eof標志。 直到您嘗試實際讀取EOF為止(只有在最后一次讀取后讀取了所有其他字符之后才讀取某些內容),才會設置EOF標志。
PS。 有一個免費功能,可以從流中讀取字符串。
std::string line;
std::getline(log, line);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.