[英]C++ sentinel in a for and while loop with a count. Stuck in infinite loop
I keep getting stuck in an infinite loop with the code. 我一直陷入代码的无限循环中。 I have to make it so you can exit using the sentinel 'q' but not iterate more than 20 times.
我必须这样做,以便您可以使用前哨'q'退出,但不能重复20次以上。 Any help will be appreciated as I'm only new to programming.
任何帮助将不胜感激,因为我只是编程的新手。
#include <iostream>
using namespace std;
int main()
{
int option; // If new member or existing member or exit
char SENTINEL = 'q';
while(option != SENTINEL)
{
for(int count = 0; count <= 20; count++)
{
// Display menu
cout << "Welcome to the forum.\n";
cout << "Are you:\n";
cout << "1. A new member\n";
cout << "2. An existing member" << endl;
cout << "To exit press 'q'\n";
cin >> option;
if (option == 1)
{
char new_name[20]; // Array to hold new member
cout << "You're a new member.\n";
cout << "Please enter your first name followed ";
cout << "by your last name.\n";
cout << "Then press return.\n";
cin >> new_name; // User enter their name
}
else if (option == 2)
{
cout << "You're an existing member." << endl;
}
}
}
}
You need to do the following: 您需要执行以下操作:
while
loop. while
循环。 You need to use one loop that has multiple conditions or break
from it within the loop. break
它。 option
a char instead of an int
. option
设为char而不是int
。 It doesn't make sense to compare option
against SENTINEL
because they are different types. option
与SENTINEL
进行比较没有意义,因为它们是不同的类型。 Making option
a char
will fix this problem. option
为char
将解决此问题。 string
class instead of char
array with 20 elements. string
类代替具有20个元素的char
数组。 Anyone whose first and last names are longer than 20 characters will cause a buffer overrun. string
safer and will automatically expand if needed. string
更安全,并且会在需要时自动扩展。 #include <iostream>
#include <string>
using namespace std;
int main()
{
char option; // If new member or existing member or exit
char SENTINEL = 'q';
for(int count = 0; count <= 20; count++)
{
// Display menu
cout << "Welcome to the forum.\n";
cout << "Are you:\n";
cout << "1. A new member\n";
cout << "2. An existing member" << endl;
cout << "To exit press 'q'\n";
cin >> option;
cin.get(); // discard newline char
if (option == '1')
{
string new_name; // string to hold new member
cout << "You're a new member.\n";
cout << "Please enter your first name followed ";
cout << "by your last name.\n";
cout << "Then press return.\n";
getline(cin, new_name); // User enter their name
}
else if (option == '2')
{
cout << "You're an existing member." << endl;
}
else if (option == SENTINEL) {
break; // break from the loop
}
}
}
Check this: Need to take newline character using getchar()
检查此:需要使用
getchar()
换行符
#include <iostream>
using namespace std;
int main()
{
int option; // If new member or existing member or exit
char SENTINEL = 'q';
while(option != SENTINEL)
{
for(int count = 0; count <= 20; count++)
{
// Display menu
cout << "Welcome to the forum.\n";
cout << "Are you:\n";
cout << "1. A new member\n";
cout << "2. An existing member" << endl;
cout << "3. To exit press '3'\n";
cin >> option;
getchar();
if (option == 1)
{
char new_name[20]; // Array to hold new member
cout << "You're a new member.\n";
cout << "Please enter your first name followed ";
cout << "by your last name.\n";
cout << "Then press return.\n";
cin >> new_name; // User enter their name
}
else if (option == 2)
{
cout << "You're an existing member." << endl;
}else if(option == 3)
{
exit(0);
}
}
}
}
You can have multiple conditions on your for loop so that it exits when count exceeds 20 or option equals 'q'. for循环上可以有多个条件,以便当count超过20或选项等于“ q”时退出。 It'll look something like this:
它看起来像这样:
int main()
{
int option; // If new member or existing member or exit
char SENTINEL = 'q';
for(int count = 0; ((count <= 20)&&(option != SENTINEL)); count++)
{
// Display menu
cout << "Welcome to the forum.\n";
cout << "Are you:\n";
cout << "1. A new member\n";
cout << "2. An existing member" << endl;
cout << "To exit press 'q'\n";
cin >> option;
if (option == '1')
{
char new_name[20]; // Array to hold new member
cout << "You're a new member.\n";
cout << "Please enter your first name followed ";
cout << "by your last name.\n";
cout << "Then press return.\n";
cin >> new_name; // User enter their name
}
else if (option == '2')
{
cout << "You're an existing member." << endl;
}
}
} }
Test the sentinel condition in the for
loop as well? 还要在
for
循环中测试前哨条件吗?
for(int count = 0; count <= 20 && option != SENTINEL; count++)
Note that to avoid undefined behavior, you should initialize option
to some value (other than SENTINEL
) or you're working with whatever garbage was left on the stack. 请注意,为避免发生未定义的行为,应将
option
初始化为某个值( SENTINEL
除外),否则,您将使用堆栈上剩下的任何垃圾。
First of all : 首先 :
option != SENTINEL
this line does not make sense you cannot compare an integer to a character, either you make both variables int or char data types option != SENTINEL
此行没有意义,您无法将整数与字符进行比较,因为您将两个变量都设置为int或char数据类型
Change char new_name[20];
更改
char new_name[20];
to an string array
to save from a lot of trouble. 转换为
string array
可以避免很多麻烦。
In addition when the user inputs q
you should exit from the loop or the program so why not use the exit(1)
method. 另外,当用户输入
q
您应该退出循环或程序,为什么不使用exit(1)
方法。
char option ;
char SENTINEL = 'q';
while(option != SENTINEL)
{
// Display menu
cout << "Welcome to the forum.\n";
cout << "Are you:\n";
cout << "1. A new member\n";
cout << "2. An existing member" << endl;
cout << "To exit press 'q'\n";
cin >> option; //<-- 1 and 2 will be char variable
if (option == '1')
{
string new_name[20];
for(int count = 0; count < 20; count++)
{
cout << "You're a new member.\n";
cout << "Please enter your first name followed ";
cout << "by your last name.\n";
cout << "Then press return.\n";
cin >> new_name[count];
}
}
else if (option == '2')
{
cout << "You're an existing member." << endl;
}
else if (option == 'q')
{
exit(1); // to exit from the loop
}
}
May you just... 愿你...
#include <iostream>
#include <string>
#include <limits>
int main() {
char option;
const char sentinel = 'q';
bool quit = false;
for(int count = 0; count <= 20 && !quit; count++) {
std::string name;
bool invalid;
do {
invalid = false;
// Display menu
std::cout << "Welcome to the forum.\n";
std::cout << "Are you:\n";
std::cout << "1. A new member\n";
std::cout << "2. An existing member\n";
std::cout << "To exit press '" << sentinel << "'\n";
std::cin >> option;
switch(option) {
case '1':
std::cout << "You're a new member.\n";
std::cout << "Please enter your first name followed ";
std::cout << "by your last name.\n";
std::cout << "Then press return.\n";
std::cin >> name;
break;
case '2':
std::cout << "You're an existing member.\n";
break;
case sentinel:
quit = true;
break;
default:
std::cout << "You entered invalid input!\n\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
invalid = true;
continue;
}
} while(invalid);
}
std::cout << "Exiting...\n";
return 0;
}
You had several issues... including: 您遇到了几个问题...包括:
using namespace std;
: Not a good idea any day of the week. while()
loop didn't made any sense. while()
循环没有任何意义。 It simply wouldn't "override" or otherwise take control over the for
loop. for
循环。 option
is of type int
, there's no way for it to notice the sentinel
input. option
的类型为int
,则它无法注意到sentinel
输入。 std::cin
would simply set the fail
bit and you would not notice it. std::cin
只会设置fail
位,而您不会注意到它。 char[20]
somewhere. char[20]
。 That's sugar for stack overflows/buffer overruns and other subtle bugs, not to even mention security issues... std::string
fixes that. std::string
解决此问题。 invalid
and quit
) are useful to get out of long-nested loops. invalid
和quit
)对于摆脱长时间嵌套循环很有用。 std::cin.clear()
cleans up any errors. std::cin.clear()
清除所有错误。 Meanwhile, std::cin.ignore()
allows you to ignore all the contents of a previous garbage input line. std::cin.ignore()
允许您忽略上一个垃圾输入行的所有内容。 I want to complement the other answers because 我想补充其他答案,因为
1-) Try this snippet: 1-)尝试以下代码段:
int option=-1;
cout<<"The initial value of option is: "<<option<<endl;
cout<<"Input a new value, please: "<<endl;
cin >> option;
cout<<"After your input, it is: "<<option<<endl;
If you input a number (like 123), it will receive it's value correctly. 如果输入数字(如123),它将正确接收其值。 If you type a letter (like q), it will become 0. If you type a mix of numbers and letters, it will try to extract a number from it until you reach a letter ( say, if you type 12q34, option will become 12 and "q34" will remain in cin's buffer)
如果键入字母(例如q),它将变为0。如果键入数字和字母的混合字母,它将尝试从中提取一个数字,直到找到一个字母为止(例如,如果键入12q34,则选项将变为12和“ q34”将保留在cin的缓冲区中)
In your code, whenever you type 'q', cin will make option go to 0, but won't forget its value. 在您的代码中,无论何时键入“ q”,cin都会使option变为0,但不会忘记其值。 So after an iteration, it won't take any input from you anymore because it still has the previous value in its memory and won't get rid of it.
因此,在迭代之后,它将不再从您那里获取任何输入信息,因为它在内存中仍具有先前的值,并且也不会摆脱它。
2-) So should you make option a char? 2-)所以你应该选择一个字符? Yes and no.
是的,没有。 If you do, typing something like "123" will create a new member with the name "23", because your program would take the '1' from "123", enter the conditional for a new member, automatically dump "23" to name and immediately go back to your first prompt.
如果这样做,则键入类似“ 123”的名称将创建一个名称为“ 23”的新成员,因为您的程序将从“ 123”中获取“ 1”,输入新成员的条件,然后自动将“ 23”转储至命名并立即返回您的第一个提示。 If that's acceptable( if you trust your user that much), go ahead.
如果可以接受(如果您非常信任用户),请继续。 Otherwise, use something like std::string and it's compare method.
否则,使用类似std :: string之类的东西,它是compare方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.