C++循环洞察请求
C++ while loop insight request
基本上,我在程序开头附近的while循环遇到了奇怪的问题,该程序检查用户对他们选择的活动的验证。当他们选择第一个活动并完成它时,它工作正常,但是当他们完成第二个活动时,它将进入运行时并不断请求用户输入有效的选择,即使他们甚至没有机会输入选项。有什么提示吗?
#include <iostream>
using namespace std;
int main()
{
const int DIGITS_CHOICE = 1, IDENTIFIER_CHOICE = 2, DOUBLE_CHOICE = 3, EXIT_CHOICE = 4;
int choice;
int userNumber, storedNumber, factor = 10, digitCounter = 0, subtractor;
char ch;
do
{
cout << "nnttPlease choose an option:nn"
<< "1. How many digits?n"
<< "2. Is this a valid C++ Identifer?n"
<< "3. Is this a double letter word?n"
<< "4. Exitn";
cout << endl << "Choice: ";
cin >> choice;
while (choice < DIGITS_CHOICE || choice > EXIT_CHOICE)
{
cout << endl << "Please enter a valid menu option: ";
cin >> choice;
}
if (choice != EXIT_CHOICE)
{
switch (choice)
{
case DIGITS_CHOICE:
cout << "Please enter an integer: ";
cin >> userNumber;
storedNumber = userNumber;
if (userNumber < 10)
{
digitCounter = 1;
}
else
{
while (userNumber != 0)
{
subtractor = userNumber % factor;
if (subtractor > 0)
{
userNumber = userNumber - subtractor;
factor *= 10;
digitCounter++;
}
else
{
userNumber = 0;
}
}
}
cout << storedNumber << " has " << digitCounter << " digit(s)." << endl;
factor = 10;
digitCounter = 0;
break;
case IDENTIFIER_CHOICE:
cout << "Please enter an identifier and press [Enter] immediately after. ";
cin >> ch;
if (ch >= 0 || ch <= 9 || ch <= 'a' || ch >= 'z' || ch <= 'A' || ch >= 'Z' || ch != '_')
{
if (ch >= 0 || ch <= 9)
{
cout << "Not a valid identifier." << endl;
cout << "Identifiers cannot start with a digit." << endl;
ch = 'n';
}
else
{
cout << "Not a valid identifier." << endl;
cout << "Inavlid character." << endl;
ch = 'n';
}
}
while (ch != 'n')
{
if (ch >= 'a' || ch <= 'z' || ch >= 'A' || ch <= 'Z')
{
cin.get(ch);
}
}
break;
case DOUBLE_CHOICE:
break;
}
}
} while (choice != EXIT_CHOICE);
return 0;
}
此外,该程序尚未完成。 第三个选项什么都没有,第二个选项几乎完成。 第一个活动虽然是完整的:)
您对有效字符的检查过于宽泛,并且没有实际意义:
if (ch >= 0 || ch <= 9 || ch <= 'a' || ch >= 'z' || ch <= 'A' || ch >= 'Z' || ch != '_')
ch
的每个可能值都将大于或等于零,因此此表达式等效于(true || a || b || c || ... || z)
并且始终解析为 true。
相反,查看它是否低于'A'
,介于'Z'
和'a'
之间或超出'z'
之间,如果是,则无效。
此外,在检查它是否是数字时,您需要检查它是否≥'0'
并≤'9'
为字符。将其与 0 和 9 的字符表示进行比较很重要,因为字符的值实际上'0'
0
(事实证明它实际上是48
(,同样'9'
:
if ( ch < 'A'
|| (ch > 'Z' && ch < 'a')
|| ch > 'z')
{
if (ch >= '0' && ch <= '9')
{
cout << "Not a valid identifier." << endl;
cout << "Identifiers cannot start with a digit." << endl;
ch = 'n';
}
else
{
cout << "Not a valid identifier." << endl;
cout << "Invalid character." << endl;
ch = 'n';
}
}
目前还不清楚之后的检查是要做什么的?它只是为了允许字母吗?在说"标识符不能以数字开头"之后,这似乎很奇怪。
if (ch >= 'a' || ch <= 'z' || ch >= 'A' || ch <= 'Z')
这基本上具有相同的问题,即每个字符都将高于"a"或低于"z"或两者兼而有之,因此这将始终解析为 true。相反,请使用&&
来检查是否在范围内:
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
希望这能解决您的问题。
逻辑不是很好;i
是有效的,但你的代码说它不是。它至少可以很好地回到菜单。您的代码的行为也像在键入字母时立即响应一样。事实并非如此。在用户按 Enter 之前,它不会打印任何内容。
似乎问题是你的变量ch
是一个char
.如果我键入的任何内容都超过单个字符,则会发生的情况是评估单个字符,而我键入的其余字符仍保留在输入流中。看起来您正在尝试处理它,但它不起作用。我不会花时间深入研究原因,部分原因是因为它很复杂,部分原因是我不知道istream
行为的全部复杂性。
我要说的是,如果你想处理多字符输入,请在任何地方使用 cin.get((,而不仅仅是有时。您可以对每个字符进行处理,但同样,在用户按 Enter 之前,不会有任何内容进入屏幕。
但这是似乎有效的代码:
#include <cctype> // isalpha() and isalnum()
#include <string> // ch is now a std::string
// ...
case IDENTIFIER_CHOICE:
cout << "Please enter an identifier and press [Enter] immediately after. ";
std::cin.ignore(256, 'n'); // needed because of getline behavior
std::getline(std::cin, ch);
if (!(isalpha(ch[0]) || ch[0] == '_')) {
cout << "Not valid.n";
break;
}
for (int i = 1; i < ch.size(); ++i) {
if (!isalnum(ch[i])) {
cout << "Not valid.n";
break;
}
}
cout << "Valid.n";
break;
// ...
使用cin
时,当您按 Enter 时,该击键将保存在输入流中。getline()
的行为方式不符合我们的预期,因为虽然cin
通常会忽略该击键,但getline
不会。所以我只是告诉cin
忽略流中任意数量的字符(但在这种情况下足够(,包括 Enter 击键(Mac 和 Linux,应该仍然适用于 Windows(我认为((。
这离无懈可击的输入验证还很远(这是不可能的(,但我认为它足以满足您正在做的事情。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 如何在boost beast http请求中设置http头
- 发送一个带有libcurl C++问题的帖子请求:s
- 在多个核心中处理一个HTTP请求
- 错误:请求非类类型为"MULTIMEDIA_FILME [500]"的成员|
- 使用 Winsock2.h C++向不和谐 API 发送 HTTP 请求时出现问题
- 每个服务器请求的内存预算
- std::getline没有在while循环中重新请求用户输入
- 请求最简单的 OpenMP 目标 GPU 示例
- 请求有关C++中嵌入 for 循环的帮助
- 错误:请求从"常量字符 [5]"转换为非标量类型"字符串"
- 使用 winsock 接收 http 请求
- QNetworkAccessManager 稍后在添加请求时删除
- 为什么我收到来自谷歌的错误请求?
- 从网链套接字请求连接设备的列表
- libcurl :C++处理多个异步请求
- 对于 http 请求,python 比 c++ 快吗?
- 通过引用传递向量是请求 std::分配器
- 为什么当通过 TCP 发送的消息速率增加时,请求-响应消息对的延迟会降低?
- C++循环洞察请求