2012-04-11 15 views
1

Zunächst einmal, danke im Voraus für Ihre Hilfe. Dieses Problem macht mich verrückt.C++: Akzeptiert keine neue C-String-Eingabe

Ich habe ein Programm, das eine C-Zeichenfolge akzeptiert, und kann dann die Anzahl der Vokale und Konsonanten zählen. Dies funktioniert ohne Probleme. Ich muss jedoch auch eine Funktion hinzufügen, mit der der Benutzer eine neue Zeichenfolge erstellen kann. Das Problem ist jedoch, wenn der Benutzer "neue Zeichenfolge" aus dem Menü auswählt, es durchläuft einfach die newString() Methode, ohne auf die Benutzereingabe zu warten. Es erstellt dann einen neuen, leeren Bildschirm.

Hier ist das gesamte Programm. Die newString() Methode ist am Ende.

#include <iostream>  
using namespace std; 

// function prototype 
void printmenu(void); 
int vowelCount(char *); 
int consCount(char *); 
int cons_and_vowelCount(char *); 
void newString(char *, const int); 

int main() { 

    const int LENGTH = 101; 
    char input_string[LENGTH];  //user defined string 
    char choice;      //user menu choice 
    bool not_done = true;  //loop control flag 

    // create the input_string object 
    cout << "Enter a string of no more than " << LENGTH-1 << " characters:\n"; 
    cin.getline(input_string, LENGTH); 

    do { 
     printmenu(); 
     cin >> choice; 
     switch(choice) 
     { 
      case 'a': 
      case 'A': 
       vowelCount(input_string); 
       break; 
      case 'b': 
      case 'B': 
       consCount(input_string); 
       break; 
      case 'c': 
      case 'C': 
       cons_and_vowelCount(input_string); 
       break; 
      case 'd': 
      case 'D': 
       newString(input_string, LENGTH); 
       break; 
      case 'e': 
      case 'E': 
       exit(0); 
      default: 
       cout << endl << "Error: '" << choice << "' is an invalid selection" << endl; 
       break; 
     } //close switch 
    } //close do 

while (not_done); 
return 0; 
} // close main 

/* Function printmenu() 
* Input: 
* none 
* Process: 
* Prints the menu of query choices 
* Output: 
* Prints the menu of query choices 
*/ 
void printmenu(void) 
{ 
    cout << endl << endl; 
    cout << "A) Count the number of vowels in the string" << endl; 
    cout << "B) Count the number of consonants in the string" << endl; 
    cout << "C) Count both the vowels and consonants in the string" << endl; 
    cout << "D) Enter another string" << endl; 
    cout << "E) Exit the program" << endl; 
    cout << endl << "Enter your selection: "; 
    return;  
} 

int vowelCount(char *str) { 
    char vowels[11] = "aeiouAEIOU"; 
    int vowel_count = 0; 

    for (int i = 0; i < strlen(str); i++) { 
     for (int j = 0; j < strlen(vowels); j++) { 
      if (str[i] == vowels[j]) { 
       vowel_count++; 
      } 
     } 
    } 
    cout << "String contains " << vowel_count << " vowels" << endl; 
    return vowel_count; 
} // close vowelCount 

int consCount(char *str) { 
    char cons[43] = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ"; 
    int cons_count = 0; 

    for (int i = 0; i < strlen(str); i ++) { 
     for (int j = 0; j < strlen(cons); j++) { 
      if (str[i] == cons[j]) { 
       cons_count++; 
      } 
     } 
    } 
    cout << "String contains " << cons_count << " consonants" << endl; 
    return cons_count; 
} // close consCount 

int cons_and_vowelCount(char *str) { 
    int cons = consCount(str); 
    int vowels = vowelCount(str); 
    int total = cons + vowels; 

    cout << "The string contains a total of " << total << " vowels and " 
      "consonants" << endl; 
    return total; 
} 

void newString(char *str, int len) { 
    cout << "Enter a string of no more than " << len-1 << " characters:\n"; 
    cin.getline(str, len); 
    return; 
} 

Antwort

6

Die Aussage cin >> choice verbraucht nur den Charakter sie, nicht der Wagenrücklauf geben, die folgt. Der folgende Aufruf lautet daher getline() eine leere Zeile. Eine einfache Lösung besteht darin, getline() anstelle von cin >> choice aufzurufen und dann das erste Zeichen als Auswahl zu verwenden.

BTW, sollte die while (not done) sofort die do { … } folgen, und die return 0 ist redundant. Außerdem sollten Sie newString am Anfang des Programms aufrufen, anstatt seinen Inhalt zu wiederholen.

+1

Eine andere Lösung ist 'cin.ignore()' nach 'cin >> choice' aufzurufen, die ein Byte aus dem Stream löscht. – jli

+0

@jli: Es ist weniger robust, z. B. wenn der Benutzer dumm ist und Leerzeichen nach den Zeichen eingibt (oder denkt, dass er "A" eingeben muss). Aber ich spalte Haare; Ihre ist eine absolut gültige Option. –

+0

Ja, da stimme ich zu, wirf es nur als Möglichkeit aus. (es würde auch an CRLF ersticken, was es noch weniger robust macht) – jli

3

cin >> choice hinterlässt eine neue Zeile im Eingabestrom .. welche die nächste getline() zu verbrauchen und zurück. Es gibt viele Möglichkeiten. Eine Möglichkeit besteht darin, cin.ignore() direkt nach cin >> choice zu verwenden.

0

Die cin >> choice verbraucht nur ein Zeichen aus dem Stream (wie bereits erwähnt). Sie sollten hinzufügen

cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); 

direkt nach cin>>choice alle Zeichen zu ignorieren, die nach dem Lesen der Wahl in den Strom kommen.

p.s. #include <limits>

Verwandte Themen