簡體   English   中英

C++ 中 fstream 的行為

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM