2014-05-09 5 views
1

Après avoir essayé pendant quelques heures pour savoir pourquoi mon code C++ ne fonctionne pas comme nécessaire, je l'ai découvert l'erreur doit se cacher dans ce morceau de code:stringstream ne pas lire comme voulu

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

Le code fait partie d'une implémentation de Game Of Life de Conway et est supposé lire un fichier contenant des informations sur une certaine configuration, puis configurer l'objet 'game' du type GameOfLife pour contenir cette configuration. Un exemple d'un fichier qui doit être lu est:

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

Le programme devrait ignorer les quatre premières règles et à la lecture de la cinquième règle, devrait définir la règle du jeu à 23/3, la règle normale. Ça fait tout ça. Il devrait également lire des blocs de code comme celui qui suit #P. Pour une raison quelconque, il ne le fait pas. Comme vous pouvez le voir, j'utilise cout comme un outil de débogage dans les parties du code qui ne fonctionnent pas comme prévu. Mon résultat attendu serait:

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

mais il est:

.** 
* 
* 

Je ne sais pas pourquoi cela est le cas. S'il vous plaît laissez-moi savoir si vous avez des conseils sur la façon de trouver l'erreur. Si vous avez besoin de plus d'informations (comme le code pour les structures utilisées comme Cel de Block), s'il vous plaît faites le moi savoir. Je n'ai pas inclus ceux-ci comme je le soupçonnais de détourner l'attention du problème; il persiste même en excluant les parties qui utilisent Block ou Cel.

Note: Les inclusions nécessaires ont été faites et le programme compile dans Eclipse sans aucune erreur ou avertissement.

+0

Votre anglais est supérieur d'un ordre de grandeur à celui de la plupart des locuteurs natifs. Malheureusement, votre code ...: p –

+0

Je ne comprends pas, pourquoi vous pensez que son 'stringstream' lié, et non une mauvaise logique de votre mise en œuvre? Je n'ai pas lu le code, mais êtes-vous absolument sûr que le jeu fonctionne dans le mauvais mode? Vous ne montrez pas, ce que vous lisez. Aussi, il n'y a pas besoin de salut et au revoir ici. Seul le problème compte =) – luk32

Répondre

0

En plus de ls.str(line); pour chaque ligne, vous avez besoin de la ligne suivante pour effacer les indicateurs d'erreur ls.

ls.clear(); 

Une façon encore plus simple peut être construire le stringstream après une ligne est lue et destructives une fois la ligne se fait.

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

Merci pour votre aide! Le code semble fonctionner maintenant. Je ne pense pas que je l'aurais vu seul avant d'abandonner complètement. :-) –

0

Deux problèmes:

  1. ls.good() est encore true après avoir lu le dernier caractère de la mémoire tampon. C'est quand vous tente de relire qu'il devient false. Ainsi, vous devriez le vérifier après votre tentative de lecture de ls pour vous assurer que vous avez réellement lu dans un personnage.
  2. ls.str() n'efface pas les indicateurs d'erreur, ce qui signifie que toutes les lectures suivantes échoueront. Par la suite, vous devrez appeler le ls.clear() ou simplement créer un nouveau canal pour chaque ligne.
Questions connexes