使用控制台的可视C++:while 循环的字符/字符串兼容性问题

Visual C++ using Console: Char/String compatibility issues with while loop

本文关键字:字符 字符串 循环 兼容性 问题 控制台 可视 C++ while      更新时间:2023-10-16
    cout << "Would you like to make another transaction? (y/n)" << endl;
    cin >> repeat_transaction;
    static_cast<char>(repeat_transaction);
    while (repeat_transaction != 'y' && repeat_transaction != 'n')
    {
        cout << "Invalid selection: Please enter y or n";
        cin >> repeat_transaction;
        static_cast<char>(repeat_transaction);
    }

在无效选择循环中,我曾经不小心按下了"mn"。我注意到控制台读出了Invalid selection...,所以,它实际上确实完成了并重新进入了while循环。但是,在此之后,控制台终止了该程序。如果您输入单个字符"a"或"y"或"n",它将按应有的方式运行。结束或不结束。这是在我尝试使用 static_cast 强制截断用户输入之前。

既然你设法让这个程序编译,我只能假设repeat_transaction被指定为char而不是std::string

当您使用 cin 获取字符时,它只获取一个字符,但不会刷新缓冲区。我相信你理解这个问题,因为你写了 这是在我尝试使用 static_cast 强制截断用户输入之前。您可以尝试在每次调用 cin >> repeat_transaction; 后使用 cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n'); 而不是 static_cast<char>(repeat_transaction);。这样做有缺点。如果输入"mn",它将按预期工作。它读取未ynm,然后刷新多余的字符,直到找到第 n 行的末尾。如果你这样做nmn会匹配,m会被扔掉。因此,在这种情况下,它将接受nm为有效并退出循环。

还有其他方法可能更容易,并为您提供更接近您正在寻找的效果。您可以使用 getline 将整行读入字符串,而不是一次读取一个字符(有关详细信息,请参阅C++文档(。然后,您可以检查字符串的长度是否不等于1字符。如果长度不是1则输入无效。如果是1,则您要检查yn。虽然基本(并且不太复杂(,但这段代码可以做一个合理的工作:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string repeat_transaction;
    cout << "Would you like to make another transaction? (y/n)" << endl;
    getline(cin, repeat_transaction);
    while (repeat_transaction.length() != 1 || (repeat_transaction != "y" && repeat_transaction != "n"))
    {
        cout << "Invalid selection: Please enter y or n";
        getline(cin, repeat_transaction);
    }
    return 0;
}

我说的是合理的工作,因为你可能会看到的一个缺陷是你想从头到尾修剪空白。如果有人输入ny,前面有spacetab,它将被视为无效(末尾的空格类似(。这对你来说可能不是问题,但我想我会提到它。

最后一点,你可能已经注意到我用了using namespace std;。我这样做是为了匹配原始问题中的内容。但是,这通常被认为是不良做法,应避免。这些StackOverflow答案试图解释这些问题。最好不要这样做,并在所有标准库引用前面加上 std:: 。例如,stringstd::stringcinstd::cin等。