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 Game Of Life и должен прочитать файл, который содержит информацию об определенной конфигурации, а затем сконфигурировать объект "игра" типа 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 ответа

Решение

В дополнение к ls.str(line); для каждой строки вам понадобится следующая строка, чтобы очистить флаги ошибок ls,

ls.clear();

Еще более простой способ - создать поток строк после чтения строки и уничтожить ее после завершения строки.

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

Две проблемы:

  1. ls.good() все еще true после того, как вы прочитали последний символ буфера. Это когда вы пытаетесь прочитать снова, что это становится false, Таким образом, вы должны проверить его после попытки чтения из ls чтобы убедиться, что вы действительно читаете в персонаже.
  2. ls.str() не сбрасывает флаги ошибок, что означает, что все последующие чтения не будут выполнены. Вам нужно будет позвонить ls.clear() после этого или просто создайте новый поток строк для каждой строки.
Другие вопросы по тегам