Stringstream不按需要阅读

时间:2014-05-09 17:01:47

标签: c++ file-io stringstream

在尝试了几个小时后找出我的C ++代码无法按要求运行的原因后,我发现错误应隐藏在这段代码中:

void loadWorld(GameOfLife& game, int rij, int kolom, string fileName){
    // Reads a .LIF-file and configures the GameOfLife object based on this info
    ifstream ifs(fileName.c_str());
    stringstream ls;
    if(!ifs) throw new fileNotFound;
    string line;
    char tempChar;
    Block tempBlock;
    vector<Cel> tempVector(0);
    string rule;
    while(ifs.good()){
        getline(ifs, line); //get next line from the file
        ls.str(line); //put it into a stringstream
        if(line!="") { //skip empty strings
            ls >> tempChar;
            if(tempChar=='#')
                ls >> tempChar; //go to the next sign
            switch(tempChar){
            case 'N':
                rule = "23/3"; //default rule
                break;
            case 'R':
                ls >> rule; //set new rule
                break;
            case 'P' :
                if(tempBlock.cellen.size()>0)
                    loadBlock(game, rij, kolom, tempBlock); //load previous block
                //new block
                tempBlock.cellen.clear();
                ls >> tempBlock.x >> tempBlock.y;
                break;
            case '.' : case '*' :
                cout << tempChar; //for testing
                tempVector.clear();
                if(tempChar=='.')
                    tempVector.push_back(Cel(0, fl_rgb_color(0,0,0)));
                else
                    tempVector.push_back(Cel(1, fl_rgb_color(0,0,0)));
                while(ls.good()){
                    ls >> tempChar;
                    cout << tempChar; //test
                    if(tempChar=='.')
                        tempVector.push_back(Cel(0, fl_rgb_color(0,0,0)));
                    else
                        tempVector.push_back(Cel(1, fl_rgb_color(0,0,0)));
                }
                tempBlock.cellen.push_back(tempVector);
                cout << endl; //test
                break;
            default:
                break;
            }
        }
    }
    loadBlock(game, rij, kolom, tempBlock);  //load last block
    int survival=0;
    int birth=0;
    extractRule(rule, survival, birth);
    game.setSurvival(survival);
    game.setBirth(birth);
}

代码是Conway的生命游戏的实现的一部分,并且应该读取包含有关特定配置的信息的文件,然后配置GameOfLife类型的对象“游戏”以包含此配置。应该读取的文件示例是:

#Life 1.05
#D Acorn
#D The most vigorously growing 7-cell
#D "methuselah" pattern.  See also RABBITS.
#N
#P -3 -1
.*
...*
**..***

程序应忽略前四条规则,在阅读第五条规则时,应将游戏规则设置为正常规则23/3。它做到了这一切。 它还应该读取像#P之后的代码块。出于某种原因,它没有这样做。正如您所看到的,我使用cout作为代码中不能按预期工作的部分的调试工具。我的预期输出是:

.*
...*
**..***

但它是:

.**
*
*

我不知道为什么会这样。如果您有关于如何查找错误的任何提示,请与我们联系。如果您需要更多信息(比如Cel of Block等使用过的结构的代码),请告诉我。我没有包括那些因为我怀疑他们会分散注意力的问题;即使排除使用Block或Cel的部件,它仍然存在。

注意:已经完成了必要的包含,并且程序在Eclipse中编译而没有任何错误或警告。

2 个答案:

答案 0 :(得分:0)

除了每行ls.str(line);之外,还需要以下行来清除ls的错误标记。

ls.clear();

更简单的方法可能是在读取一行后构造字符串流,并在完成一行后对其进行破坏。

while(getline(ifs, line)) {
    istringstream ls(line);
    // ...
}

答案 1 :(得分:0)

两个问题:

    读取缓冲区的最后一个字符后,
  1. ls.good()仍为true。当您尝试再次阅读它变为false时。因此,您应该在} 尝试阅读之后检查以确保您实际读取了一个字符。
  2. ls不会清除错误标志,这意味着所有后续读取都将失败。您需要在此之后调用ls.str(),或者只是为每一行构建一个新的字符串流。