fstream在C ++中的行为

时间:2018-11-13 19:08:20

标签: c++ fstream

我编写了以下脚本,应该从文件中读取该脚本:

    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,并跳过36。但是,它将卡住并继续打印5 0,并永远继续打印5 0。我将匹配项放入b,这是一个整数,但我不知道为什么将其循环。输入是否不应该一次读取匹配4,尝试读取/写入5并匹配,然后用第4行和第5行进行匹配?然后,它应该接下来读取数字1和4,然后从数字6匹配。

我也将理解,由于单词不适合整数,它将再次在第五行读取匹配,但这不是它的作用。

它返回到已经读取的第四行中的匹配项,然后再次读取。为什么会这样?

1 个答案:

答案 0 :(得分:0)

当您使用>>进行阅读时,行插入与空格的处理方式相同:它们只是被跳过的更多空白。这表示您看到

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())毫无价值。文件的末尾永远无法到达。该程序将永远循环,可能会打印最后读取的内容。成功阅读。

解决此问题完全取决于您要执行的操作,如果您有没有两个数字的 match 行,但是典型的框架看起来像

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,您可以决定将其放入TextView文件。