Domanda

After having tried for a few hours to find out why my C++ code doesn't work as required, I've found out the error should be hiding within this piece of code:

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);
}

The code is part of an implementation of Conway's Game Of Life and is supposed to read a file that contains information about a certain configuration, then configure the object 'game' of the type GameOfLife to contain this configuration. An example of a file that should be read is:

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

The program should ignore the first four rules and upon reading the fifth rule, should set the rule of game to 23/3, the normal rule. It does all that. It should also read blocks of code like the one following #P. For some reason, it does not do so. As you can see, I use cout as a debugging tool in the parts of the code that do not work as expected. My expected output would be:

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

but it is:

.**
*
*

I have no idea why this is the case. Please let me know if you have any tips on how to find the error. If you need more information (like code for used structures like Cel of Block), please let me know. I didn't include those as I suspected they would distract from the problem; it persists even when excluding the parts that use Block or Cel.

Note: The necessary includes have been made and the program compiles in Eclipse without any errors or warnings.

È stato utile?

Soluzione

In addition to ls.str(line); for each line, you need the following line to clear error flags of ls.

ls.clear();

An even simpler way may be construct the stringstream after a line is read and destruct it once the line is done.

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

Altri suggerimenti

Two problems:

  1. ls.good() is still true after you read the last character of the buffer. It's when you attempt to read again that it becomes false. Thus, you should check it after your attempted read from ls to ensure that you actually read in a character.
  2. ls.str() does not clear the error flags, which means that all subsequent reads will fail. You'll need to call ls.clear() after that, or simply construct a new stringstream for each line.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top