Hello i'm trying to use a do-while loop to check the input and repeat the prompt until the user types in a correct integer. So that's my code:
#include <iostream>
#include <stdio.h>
#include <ctype.h>
int main ()
{
int a;
do
开发者_高级运维 {
printf("Please type in your number: ");
}while(scanf_s("%d", &a) == 0);
std::cin.get();
std::cin.get();
return 0;
}
Well it seems to work. When I type in a number the program runs correctly. But when I type in a letter an infinite loop starts. Sincerly I don't know where the problem is.
Again, I suggest reading a line into a string and then trying to parse that string according to your needs. If the parse fails, simply prompt the user again. You can bury the messy details in a function template:
#include <iostream>
#include <sstream>
#include <string>
template <typename T>
T read(std::string prompt)
{
for (; ;)
{
std::cout << prompt;
std::string line;
getline(std::cin, line);
std::istringstream ss(line);
T x;
if ((ss >> x) && (ss >> std::ws).eof()) return x;
}
}
int main ()
{
int a = read<int>("Please type in your number: ");
std::cout << "You entered " << a << '\n';
}
Here's what's going on -- I'll go through step by step. Starting from the do
:
- output: Please type in your number:
- call to
scanf
Scanf finds thatstdin
is empty, and therefore waits for a line to be typed in. - input :
letter
(note that the input buffer now contains "letter") scanf
attempts to parse the string as an integer. Parsing fails before it consumes any characters. Therefore the buffer still contains "letter"scanf
returns EOF (error)- output: Please type in your number:
- call to
scanf
--scanf
sees that there's already waiting input instdin
scanf
attempts to parse the buffer as an integer.....
This will go on forever because scanf
will never consume the characters from the buffer. You can solve the problem by correctly checking for an error return code from scanf
.
First of all never ever use scanf
as its one hell of a dangerous function.
If you want to stick with C you should use fgets
to read the input from the user to a buffer and then atoi
to convert the input from the user to an integer.
Note: fgets always adds the 'enter' in to the buffer so you want to strip it off before converting the content of the buffer.
this could be easily done as follow:
_buffer[strlen(_buffer)-1] = '\0';
I have modified my code so that it works now. But sincerly it just works for numbers and letters. I want it to work with every char. For example "!?%". I have already tried to change the "isalnum" by "isascii" but that does not work.
#include <stdio.h>
#include <ctype.h>
int main ()
{
int a;
int b = 1;
char c ;
do
{
printf("Please type in a number: ");
if (scanf("%d", &a) == 0)
{
printf("Your input is not correct\n");
do
{
c = getchar();
}
while (isalnum(c));
ungetc(c, stdin);
}
else
{
printf("Thank you! ");
b--;
}
}
while(b != 0);
getchar();
getchar();
return 0;
}
@ ordo
Blockquote
I have modified my code so that it works now. But sincerly it just works for numbers and letters. I want it to work with every char. For example "!?%". I have already tried to change the "isalnum" by "isascii" but that does not work.
Blockquote
You can use
if(userInput>='!'&& userInput<= '~') // refer ASCII chart between !and ~. { exit=0; }
http://www.cdrummond.qc.ca/cegep/informat/professeurs/alain/images/ASCII1.GIF
int main ()
{
int a;
char userInput,exit=1;
do
{
printf("Please type in your number: ");
userInput=getch();
if(userInput=='1') // suppose the correct input is 1.
{ exit=0; }
}while(exit);
std::cin.get();
std::cin.get();
return 0;
}
If the input is between 0
and 9
...
if(userInput>='0'&& userInput<= '9') // suppose the correct input is 1.
{ exit=0; }
Note that we have to use ' ' signs
You can use getchar()
function
do
{
printf("Please type in your number: ");
}while((getchar() - '0') == 0);
精彩评论