[英]Behaviour of fstream in C++
我制作了以下腳本,應該從文件中讀取:
char match[] = "match";
int a;
int b;
inp >> lin;
while(!inp.eof()) {
if(!strcmp(lin, match)) {
inp >> a >> b;
cout << a << " " << b <<endl;
}
inp >> lin;
}
inp.close();
return num_atm;
}
它應該讀取所有單詞,如果一行以 match 開頭,它還應該打印該行的其余部分。
我的輸入文件是這樣的:
match 1 2 //1
match 5 2 //2
nope 3 6 //3
match 5 //4
match 1 4 //5
match 5 9 //6
它將正確打印 1 2, 5 2,並跳過 3 6。但是,它會卡住並繼續打印 5 0 並永遠繼續打印 5 0。 我得到匹配被放入 b,這是一個整數,但我不明白為什么這是循環。 輸入讀取不應該匹配 4 一次,嘗試讀/寫 5 並匹配,然后用第 4 行和第 5 行的匹配來完成嗎? 然后它應該接下來讀取數字 1 和 4,然后從數字 6 開始匹配。
我也明白,由於單詞不適合整數,它會再次讀取第五行中的匹配,但這不是它的作用。
它返回到它已經閱讀的第四行中的匹配項,並再次閱讀。 為什么是這樣?
當您使用>>
行尾閱讀時,其處理方式與空格相同:它們只是更多的空白被跳過。 這意味着你看到
match 1 2
match 5 2
nope 3 6
match 5
match 1 4
match 5 9
但是程序看到
match 1 2 match 5 2 nope 3 6 match 5 match 1 4 match 5 9
讓我們快進到事情向南的地方
流的內容:
nope 3 6 match 5 match 1 4 match 5 9
加工
inp >> lin; // reads nope stream: 3 6 match 5 match 1 4 match 5 9
if(!strcmp(lin, match)) { // nope != match skip body
}
inp >> lin; // reads 3 stream: 6 match 5 match 1 4 match 5 9
if(!strcmp(lin, match)) { // 3 != match skip body
}
inp >> lin; // reads 6 stream: match 5 match 1 4 match 5 9
if(!strcmp(lin, match)) { // 6 != match skip body
}
inp >> lin; // reads match stream: 5 match 1 4 match 5 9
if(!strcmp(lin, match)) { // match != match Enter body
inp >> a >> b; // reads 5 and fails to parse match into an integer.
// stream: match 1 4 match 5 9
// stream now in failure state
cout << a << " " << b <<endl; // prints 5 and garbage because b was not read
}
inp >> lin; // reads nothing. Stream failed
if(!strcmp(lin, match)) { // match != match Enter body
inp >> a >> b; // reads nothing. Stream failed
// stream: match 1 4 match 5 9
// stream now in failure state
cout << a << " " << b <<endl; // prints g and garbage because b was not read
}
因為什么都沒有讀過,所以while(!inp.eof())
完全沒有價值。 永遠無法到達文件的末尾。 該程序將永遠循環,可能會打印上次讀取的內容。 成功閱讀。
如果您有一條沒有 2 個數字的匹配行,解決這個問題完全取決於您想要做什么,但典型的框架看起來像
std::string line;
while(std::getline(inp, line) // get a whole line. Exit if line can't be read for any reason.
{
std::istringstream strm(line);
std::string lin;
if(strm >> lin && lin == match) // enters if lin was read and lin == match
// if lin can't be read, it doesn't matter.
// strm is disposable
{
int a;
int b;
if (strm >> a >> b) // enters if both a and b were read
{
cout << a << " " << b <<"\n"; // endl flushes. Very expensive. just use a newline.
}
}
}
輸出應該是這樣的
1 2
5 2
1 4
5 9
如果您想使用match 5 ...那么,如果文件中沒有b
,那么您想在b
放入什么取決於您。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.