2010-02-20 4 views
0

Je reçois une boucle infinie lorsque j'utilise le code suivant en C++ et je ne comprends pas pourquoi. Je suspecte que le problème est dans la fonction input_words(). Voici le code:C++ Unwanted infinite while loop

#include<iostream> 
using namespace std; 

string input_words(int maxWords) { 
    int nWord = 0; 
    string words[maxWords]; 
    string aWord = ""; 
    while (aWord != "Quit" && nWord < maxWords) { 
     cout << "Enter a number ('Quit' to stop): "; 
     getline (cin, aWord); 
     words[nWord] = aWord; 
     nWord++; 
    } 
    return *words; 
} 

int num_words (string words[], int maxWords) { 
    int numWords = 0; 
    for (int i=0; i<maxWords; i++) { 
     if (words[i] == "Quit") { 
      break; 
     } 
     numWords++; 
    } 
    return numWords; 
} 

int main() { 

    const int MAX_WORDS = 100; 
    string words[MAX_WORDS] = input_words(MAX_WORDS); 

    int lenWords = num_words(words, MAX_WORDS); 
    cout << "\nThere are " << lenWords << " words:\n"; 

    for (int i=0; i<MAX_WORDS; i++) { 
     if (words[i] == "Quit") { 
      break; 
     } 
     cout << words[i] << "\n"; 
    } 
    return 0; 
} 

Plus précisément, je ne peux pas sortir, même quand je tape « Quitter » lorsque vous êtes invité pour un mot. Comment pourrais-je résoudre ceci? Je sais que ce code est Noob :) Je viens juste de commencer sur

+2

Cela devrait fonctionner correctement. En outre, il s'agit d'une extension, et non C++: 'string mots [maxWords];' Dans les tableaux C++ ont une taille constante. Si vous voulez un tableau dynamique, vous devriez utiliser 'std :: vector ', et ajouter des choses avec 'push_back'. Cela supprime également votre besoin d'une taille maximale. Enfin, ceci: 'return * words; 'va retourner seulement la première chaîne. Peut-être que votre intention était de retourner le tableau entier, auquel cas faites votre type de retour 'std :: vector ' et renvoyez le vecteur. – GManNickG

+0

@GMan: afaik g ++ prend en charge des tableaux de taille dynamique sur la pile, mais sachez que cela n'est pas conforme à la norme. – JPvdMerwe

+0

Merci beaucoup GMan! Je pense que vous auriez dû poster (ou poster) ceci comme réponse. Je viens de poster une nouvelle question sur la déclaration d'un vecteur avant de lire votre commentaire. J'ai aussi pensé qu'un vecteur était la solution, mais je n'ai pas réussi à le déclarer. – Morlock

Répondre

2

J'ai modifié la fonction de telle manière:

string input_words(int maxWords) { 
    cout << "started" << endl; 
    int nWord = 0; 
    string words[maxWords]; 
    string aWord = ""; 
    while (aWord != "Quit" && nWord < maxWords) { 
     cout << "Enter a number ('Quit' to stop): "; 
     getline (cin, aWord); 
     words[nWord] = aWord; 
     nWord++; 
    } 
    cout << "finished" << endl; 
    return *words; 
} 

Après avoir entré Quit, il imprime "fini", puis "a commencé" à nouveau. Votre code appelle la fonction plusieurs fois.

Le problème est que la fonction retourne une seule chaîne. de sorte que la ligne

string words[MAX_WORDS] = input_words(MAX_WORDS); 

semble appeler la fonction input_words MAX_WORDS fois.

Une bonne façon serait de passer à vector<string>:

vector<string> input_words(int maxWords) { 
    vector<string> words; 
    string aWord; 
    while (aWord != "Quit" && nWord < maxWords) { 
     cout << "Enter a number ('Quit' to stop): "; 
     getline (cin, aWord); 
     words.push_back(aWord); 
    } 
    return words; 
} 

... 
vector<string> words = input_words(MAX_WORDS); 
+0

Bonne capture qu'il appelle input_words() MAX_WORDS fois. – Harvey

+0

@Vlad En effet, et vous l'avez même suggéré AVANT de mettre tout le code, y compris les mots [MAX_WORDS] bit :) Merci beaucoup pour la mise en œuvre de vecteur, c'est exactement où je me dirigeais, mais je trouve difficile pour un débutant pour obtenir des informations sur les méthodes C++ existantes. (Je viens de Python, où l'aide() est toujours prête à être utilisée). Toute suggestion d'un site favori où trouver ce genre de choses? Je suis juste tombé sur http://www.cppreference.com/wiki/ mais s'il y en a de meilleurs ou d'autres, je suis tout ouvert! – Morlock

+0

@Morlock: pour un démarrage rapide, j'ai utilisé http://www.icce.rug.nl/documents/cplusplus/ il y a plusieurs années. http://stackoverflow.com est vraiment très bon aussi! :-) – Vlad

0

C++ J'ai essayé le programme de test suivant, cela fonctionne:

{0,506}$> cat testcin.cpp && make testcin && ./testcin.exe 
#include <iostream> 
using namespace std; 

int main() 
{ 
    const int maxWords = 5; 
    int nWord = 0; 
    string words[maxWords]; 
    string aWord = ""; 
    while (aWord != "Quit" && nWord < maxWords) { 
     cout << "Enter a number ('Quit' to stop): "; 
     getline (cin, aWord); 
     words[nWord] = aWord; 
     nWord++; 
    }  
} 

make: `testcin' is up to date. 
Enter a number ('Quit' to stop): test 
Enter a number ('Quit' to stop): Quit 

[[email protected]] [20:53:53] [~/c++] 
{0,507}$> 
0

Le problème, je pense que dans votre principale où vous revenez le résultat de input_words() qui est un string pour initialiser les mots dans main() qui est de type string[]. C'est définitivement ce problème.

réécrite pour utiliser vector:

#include<iostream> 
#include<vector> 
#include<string> 
using namespace std; 

vector<string> input_words(int maxWords) { 
    int nWord = 0; 
    vector<string> words; 
    string aWord = ""; 
    while (aWord != "Quit" && nWord < maxWords) { 
     cout << "Enter a number ('Quit' to stop): "; 
     getline (cin, aWord); 
     words.push_back(aWord); 
     nWord++; 
    } 
    return words; 
} 

int num_words (vector<string> words) { 
    // return words.size(); 

    int numWords = 0; 
    vector<string>::iterator it = words.begin(); 
    for (; it != words.end(); it++) { 
     if (*it == "Quit") { 
      break; 
     } 
     numWords++; 
    } 
    return numWords; 
} 

int main() { 

    const int MAX_WORDS = 100; 
    vector<string> words = input_words(MAX_WORDS); 

    int lenWords = num_words(words); 
    cout << "\nThere are " << lenWords << " words:\n"; 

    vector<string>::iterator it = words.begin(); 
    for (; it != words.end(); it++) { 
     if (*it == "Quit") { 
      break; 
     } 
     cout << *it << endl; 
    } 
    return 0; 
} 

Oubliez ce qui suit, le getline() C++ supprime le '\ n' automatiquement.

Avez-vous vérifié si vos mots getline() ont des nouvelles lignes à la fin d'eux? C'est,

"Quit" != "Quit\n". 
+0

J'ai eu une implémentation de travail dans une boucle while qui fonctionnait parfaitement (un peu comme la réponse de Vlad). J'ai alors essayé d'en faire une fonction et je suis resté coincé dans la boucle infinie. Je modifie la question pour ajouter le code complet, pas seulement la fonction. – Morlock

+1

[Documentation] (http://www.cplusplus.com/reference/string/getline/) indique: Si le délimiteur est trouvé, il est extrait et mis au rebut, c'est-à-dire qu'il n'est pas stocké et la prochaine opération de saisie commencera après ça. – Vlad

+0

@Vlad: ouais je regardais le C getline par erreur. – Harvey