由于缓冲值-1导致无限循环?

时间:2015-03-20 12:58:02

标签: c++ infinite-loop cin

我正在上课这个程序。它的大小应该是10个或更少的字符,并使用toupper()调用将每个字符单独更改为大写。赋值的要求是对包含单词和toupper()的数组中的每个字符使用'\n'。这是我的代码:

int main(int argc, char *argv[])
{

    char again = ' ';
    char word[11];

    for(int count=0; count<11; count++){
            word[count] = ' ';
    }

    while(true){

        for(int clear=0; clear < 11; clear++){
            word[clear] = ' ';
        }

        system("CLS");
        cout << "Please provide a lowercase word!" << endl;
        cin.getline(word, 11);

        for(int letter = 0; letter < 11; letter++){
            system("CLS");
            if(letter < 10){
                word[letter] = toupper(word[letter]);
            }
            for(int printw = 0; printw < 11; printw++){
                cout << word[printw];
            }
            Sleep(200);
        }

        cout << endl;

        while(true){
            cout << "Would you like to Repeat or Quit? (R/Q)" << endl;
            cin.get(again);
            cin.get();

            tolower(again);

            if(again == 'r' || again == 'q'){
                break;
            }
            else{
                cout << "That was an invalide input!" << endl;
            }
        }

        if(again == 'q'){
            break;
        }
    }

    system("PAUSE");
    return EXIT_SUCCESS;
}

该程序适用于1到10个字符,但如果用户决定输入大于10个字符的字符串,程序将大写前10个,然后在询问用户是否愿意时进入无限循环再试一次。当发生这种情况时,它将继续返回“这是一个无效的输出!”并在下一行重复或退出的下一个提示。它不会等待输入,我已经尝试用cin.ignore()清除缓冲区。

我尝试使用多个cout << cin.get() << endl;行检查缓冲区中的值,并且它们都返回ascii值为-1。我认为这意味着它会抛出一个failbit异常,但我确实不确定。

2 个答案:

答案 0 :(得分:1)

您应该使用string来存储输入,而不是使用固定大小的字符数组。您可以使用getline来读取cin中的一行,如下所示:

string input;
...
getline(cin, input);

这将读取整行,无论它的长度或实际处理的字符数。

答案 1 :(得分:1)

您在此处看到的是cin.getline(char* s, streamsize n)的预期行为
来自istream::getline的C ++参考:

  

如果函数不提取字符,则设置failbit标志,或 if   一旦(n-1)个字符找不到分隔字符   已写入s

如果用户输入的字长超过10个字符,则cin会将前10个字符写入word,并将其内部标志设置为失败,因为没有看到分隔符\n(换行符)。 / p>

如果你想坚持现有的解决方案,你可以通过以下方式解决这个问题:

const int SIZE = 11;

...

cin.getline(word, SIZE);
if (cin.fail() && cin.gcount() == SIZE-1) { // failed because user entered a word longer than 10 chars
    word[SIZE-1] = '\0';    // make sure to null terminate
    cin.clear();            // clear the failure from cin
    cin.ignore(256, '\n');  // ignore the leftover input from cin until next newline
}

您需要清除failbit并忽略剩余输入。 256只是一个足够大的数字,为了超级安全,你可以使用cin.ignore(numeric_limits<streamsize>::max(), '\n');(不要忘记#include <limits>

PS你可能最好一次用cin.get(char&amp; c)读取一个字符。