I want that the program controls the user's input (must be a char/letter), but if I put "xx" it goes out of the loop, why?
char c;
int i = 0;
do{
if(i!=0){
printf("Wrong!\n");
}
printf("Insert char: ");
scanf(" %c", &c);
i++;
}while(c<'a' && c>'z' && c<'A' && c>'Z');
-----> Edit/correct
This piece of code should read a single character from the keyboard (must be a letter, it does not matter whether it is lowercase or uppercase), if it were not so I write "wrong".
As you told me I corrected the condition of the do/while, now the code is:
do{
if(i!=0){
printf("Wrong!\n");
}
printf("Insert char: ");
scanf(" %c", &c);
i++;
}while(!((c>='a' && c<='z') || (c>='A' && c<='Z')));
Input examples:
What I expect
'a' -> exit to the loop
'aa' -> remain in the loop
'.' -> remain in the loop
'..' -> remain in the loop
What happens
'a' -> exit to the loop
'aa' -> exit to the loop
'.' -> remain in the loop
'..' -> remain in the loop (but it print me two time "wrong")
If I do not put the space in the scanf, so ("%c"), the program prints me automatically "wrong" and "insert char" (it just makes a loop)
(p.s. I apologize if I had not explained very well the problem before)
Your condition for
while(c<'a' && c>'z' && c<'A' && c>'Z');
will never be true.
but if I put "xx" it goes out of the loop, why?
Since do-while is an exit-condition loop, the only time you enter the loop is the first time.
The specifier %c indicates a character. Accordingly, your while loop checks for single characters but you give as an input a string.
If you want to input a string, change your scanf statement to :
scanf("%s", &s);
as the specifier %c indicates a string. You will need to modify your while loop accordingly in order for your condition to become true at some point.
while(c<'a' && c>'z' && c<'A' && c>'Z')
is always false, that's why.
If it were true:
if(i!=0){ printf("Wrong!\n");}
will always print false(except the first time).
I don't know exactly what you want.
Your problem is in the condition, it's always false.
Example code:
#include <cstdio>
#include <cctype>
int main ()
{
char c;
do scanf("%c", &c);
while(tolower(c)<'a' || tolower(c)>'z');
printf("%c\n",c);
return 0;
}
Related
I'm going through lessons at S.Prata book: 'C Primer Plus'. Chapter 6, control question #8:
// Given the input Go west, young man!, what would each of the following
// programs produce for output? (The ! follows the space character in the
// ASCII sequence.)
#include <stdio.h>
int main(void) {
char ch;
scanf("%c", &ch);
while (ch != 'g') {
printf("%c", ch);
scanf("%c", &ch);
}
return 0;
}
The thing is... as far as I know %c in scanf should be used for a single character, not for a phrase like 'Go west, young man!'. Why this program read all the line and stores all of it (except last word), not only first character? Does it automatically store stuff in scanf as an array?
I thought it will print just 'G'... But it actually prints 'Go west, youn'. Why? It's not %s, but %c.
I suppose it could be because %c stores all input to 'char'.. but in specifications it said that it stores only single character, not several ones.
There is a loop, which has the scanf() in it's body
while ( ch != 'g' )
so, it keeps on reading the inputs present in the buffer, until it finds a 'g'.
So, for the input
'Go west, young man!'.
^---------------- here is the 'g'
It'll keep on reading the characters one by one, in each iteration till it reads the 'g' and encounters the exit criteria for the loop.
The character ch will never store a whole string, it only stores one character. The output you're getting is NOT given by a single printf execution, it's by multiple executions of printfs (The loop enters multiple times). You can confirm that by changing the code to:
#include <stdio.h>
int main(void)
{
char ch;
scanf("%c", &ch);
while (ch != 'g')
{
printf("PRINTING: %c\n", ch);
scanf("%c", &ch);
}
return 0;
}
Now, let's see why the loop enters multiple times.
You entered many characters in the scanf outside the loop, then in the loop you expect it to print the first character, which is totally correct. BUT, you think it will wait for the user input again, which is not correct. In the first scanf, when you entered multiple characters, it just read the first one. But there is somehow a hidden cursor in the stdin (standard input) that keeps track of what has been read. When you entered "Go west, young man!", the G is stored in ch and the cursor is put before the o. When you next call scanf, it will look at the cursor position and finds an o, so it won't wait for user input and just reads it. etc.
To summarize, I suspect your problem is that you misunderstand how scanf works. You think that it will always wait for user input whenever called. That is not the case, it may read from the previous input.
If you want the next scanfs to ignore the long first input, you should actually read it (or seek the stdin which will work in Windows but not Linux). Example:
#include <stdio.h>
int main(void)
{
char ch;
scanf("%c", &ch);
while (getchar() != '\n'); // Get to the end of the stdin.
// The previous line can be replaced with fseek(stdin, 0, SEEK_END); but it will work under Windows only.
while (ch != 'g')
{
printf("PRINTING: %c\n", ch);
scanf("%c", &ch);
}
return 0;
}
The program simply reads all characters one by one of the input.
So for an input such as
Go west, young man!
then the first call to scanf reads the single character 'G'. Then in the loop you print that single 'G', followed by reading the single character 'o'. Then in the next iteration of the loop you print the single character 'o' (that you read in the previous iteration) and then read the space ' '. And so on.
Also note that 'G' is not equal to 'g'. Character comparison is case-sensitive.
int main (int argc, char *argv [])
{
char a = 'v';
for (int i = 0; a != 'x'; )
{
printf("Enter 'a' : ");
scanf("%c",&a);
}
return 0;
}
I ran it and gave input k. When I hit enter after this , why my printf runs 2 times when loop runs second times?
To understand this behaviour, we can simulate step-by-step the execution.
printf("Enter 'a' : ");
scanf("%c",&a); // User type in example 'a' and presses enter.
scanf "bufferize" a\n and places in a the value 'a'
The loop condition isn't satisfied, since 'a' == 'x' is false
printf("Enter 'a' : ");
scanf("%c",&a); // The buffer still contains `'\n'`
Since the buffer still contains unconsumed data, the next character ('\n') is placed in a and the loop continues.
The loop condition isn't satisfied, since '\n' == 'x' is false
printf("Enter 'a' : ");
scanf("%c",&a); // The buffer is empty now.
This gives you the illusion that the loop displays twice the printf, but in fact, the scanf kept reading the buffer without the need of user input.
If you enter more characters, in example qwerty, "Enter 'a' : " will be displayed 7 times, because "qwerty" contains 6 characters + '\n'
Note that using while (a != 'x') would suit better your needs than for (int i = 0; a != 'x'; )
When you use scanf and %c, it reads any character -- including the newline character you get when you press the ENTER key.
So if you run the program and type
a <Return>
you take two trips through the loop: one to read the 'a' and one to read the '\n'. If you type
<Space> <Space> a <Return>
it makes four trips through the loop. And if you type
x <Return>
it only makes one trip through the loop, because it notices you typed the 'x', and exits.
Things will become a little more clear if you print out each character you receive:
for (int i = 0; a != 'x'; )
{
printf("Enter 'a' : ");
scanf("%c",&a);
printf("you typed %d = %c\n", a, a);
}
When you see it printing
you typed 10 =
that's one of the newlines. (The value of '\n' is 10 in ASCII.)
I said that %c reads any character -- but that's somewhat unusual. Most of scanf's other format specifiers -- %d, %f, %s, etc. -- skip over "whitespace" -- that is, spaces, tabs, newlines, and a few others. But %c does not skip over those, because its job is to read exactly one character, and someone thought you might want to use it to read whitespace characters, too.
For starters this loop
for (int i = 0; a != 'x'; )
does not make sense at least because the variable i is not used within the loop.
Also this prompt
printf("Enter 'a' : ");
only confuses users. You are asking the user to enter the character 'a' while the loop stops when the character 'x' is entered.
This call of scanf
scanf("%c",&a);
reads all characters including white-space characters. It is the reason why the loop iterates one more. You have to write
scanf( " %c", &c );
^^^
In this case white spaces will be skipped.
From the C Standard (7.21.6.2 The fscanf function)
5 A directive composed of white-space character(s) is executed by
reading input up to the first non-white-space character (which remains
unread), or until no more characters can be read
The program can look the following way
#include <stdio.h>
int main(void)
{
char c;
do
{
printf( "Enter a character ('x' - exit): " );
} while ( scanf( " %c", &c ) == 1 && c != 'x' );
return 0;
}
What I am trying to accomplish is prompting the user with the question of do they want to run the program again. They either type y or n. If y, it reruns the program. If no, it stops the program. Anything other than those two will prompt an error and ask the question again. I'm used to C# where strings are not complicated, but in C, I guess there technically isn't strings, so we have to use either char arrays or char pointers. I've tried both, none that work that way I want, but I'm probably the problem. This is what I have.
char answer[1] = "a";
while (strcmp(answer, "y") != 0 || strcmp(answer, "n") != 0)
{
printf ("\n\nWould you like to run the program again? Type y or n. Then, hit Enter.");
scanf ("%c", answer);
if (strcmp(answer, "y") == 0)
{
main();
}
else if (strcmp(answer, "n") == 0)
{
continue;
}
else
{
printf ("\nERROR: Invalid input was provided. Your answer must be either y or n. Hit Enter to continue.");
F = getchar();
while ((getchar()) != F && EOF != '\n');
}
}
I have other while loops similar to this that work as expected, but use a float. So I'm assuming the problem is me using char here. What happens right now is that it doesn't even prompt the user for the question. It just asks the question and shows the error right afterwards. I'm sure there are other things wrong with this code, but since I can't get the prompt to work, I cannot test the rest of it yet.
I suggest using a light weight getchar() instead of the heavy scanf.
#include <stdio.h>
int c; /* Note getchar returns int because it must handle EOF as well. */
for (;;) {
printf ("Enter y or n\n");
c = getchar();
switch (c) {
case 'y': ...
break;
case 'n': ...
break:
case EOF:
exit(0);
}
}
"a" is a string literal == char id[2]={'a','\0'} //Strings are
char arrays terminated by zero, in C
'a' is a char literal
strcmp is just "compare each char in two strings, until you hit '\0'"
scanf ("%c", ___); expect an address to write to as the second
argument. Functions in C cannot modify their arguments (they don't
have access to them--they get their own local copy) unless they have
a memory address. You need to put &answer in there.
Jens has already basically answered the question, you most likely want to use getchar so that you can detect EOF easily. Unlike scanf("%c",...), getchar will not skip spaces, and I believe both versions will leave you with the unprocessed rest of the input line (a newline character ('\n') at least) after each getchar. You might want to something like
int dump;
while((dump=getchar())!='\n' && dump!=EOF) {};
So that you discard the rest of the line once you've read your first character of it.
Otherwise, the next getchar will get the next unprocessed character of the same line. ('\n' if the line was a single letter).
Here is one way to do it. It is by no means the only way to do it, but I think it accomplishes what you want. You should not call the main function recursively.
#include <stdio.h>
#include <stdlib.h>
void run_program()
{
printf("program was run.");
}
int main() {
char answer[2] = "y\0";
int dump;
do {
if (answer[0] == 'y')
{
run_program(); /* Not main, don't call main recursively. */
}
printf ("\n\nWould you like to run the program again? Type y or n. Then, hit Enter.\n");
scanf ("%1s", answer);
/* Dump all other characters on the input buffer to
prevent continuous reading old characters if a user
types more than one, as suggested by ThorX89. */
while((dump=getchar())!='\n' && dump!=EOF);
if (answer[0] != 'n' && answer[0] != 'y')
{
printf ("Please enter either y or n\n");
}
} while (answer[0] != 'n');
return 0;
}
Using %s instead of %c, reads in the new line so that the new line character is not in the stdin buffer which would become answer then next time scanf was called.
The run_program function is just a function where you would put your program's logic. You can call it whatever you want. I did this to separate out the menu logic from the logic of the actual program.
Well, you are comparing two strings instead of characters.
If you want to compare two character you have to follow this syntax:
char c;
scanf("%c",&c);
if(c == 'y')
//do something
else
//do nothing
This question already has answers here:
Using getchar() in a while loop
(3 answers)
Closed 9 years ago.
I'm currently learning C and C++ on my own. In this little "program practice" I ask the user to enter either 'i' or 'd' to know whether they want to work with integers or decimal (float) numbers. I have a while loop that makes sure the user enter 'i' or 'd' by telling them if they entered the wrong char. For some reason, the prompt inside the while loop prints two times before going to the getchar(). I'm having a bit of hard time understanding what's happening under the hood in this situation. Any help is super appreciated. I'm using Xcode (don't know if it's relevant).
#include <stdio.h>
int main()
{
char action;
printf("Please enter 'i' to work with integers or 'd' to work with decimals.\n\n");
scanf("%c", &action);
while (action != 'i' || action != 'd')
{
printf("You didn't entered the right command. Please try again (i/d)\n");
action = getchar()
}
}
So what I'm getting as an output is this:
You didn't entered the right command. Please try again (i/d)
You didn't entered the right command. Please try again (i/d)
What is happening is that when you enter a character and hit a return, you are actually entering two characters - the character and the return character ('\n'). The loop executes once for each character. Which is why you see it go through twice.
The trick is to filter out the return character explicitly, like so:
#include <stdio.h>
int main()
{
char action;
printf("Please enter 'i' to work with integers or 'd' to work with decimals.\n\n");
scanf("%c", &action);
while (action != 'i' || action != 'd')
{
if (action != '\n')
{
printf("You didn't entered the right command. Please try again (i/d)\n");
}
action = getchar();
}
}
As correctly diagnosed by Ziffusion in his answer, you get the double prompt because you get the newline after the user's incorrect input as a separate character, and that too is neither i nor d.
Here is a rewrite with some improvements:
#include <stdio.h>
int main(void)
{
char action = '\0';
printf("Please enter 'i' to work with integers or 'd' to work with decimals: ");
while (scanf(" %c", &action) == 1 && action != 'i' && action != 'd')
printf("You didn't enter the right command. Please try again (i/d): ");
printf("Action selected: %d\n", action);
}
What's changed?
The prompt doesn't end with a newline, so the user's response appears immediately after it. Standard I/O normally synchronizes standard output and standard input so that the prompt will be flushed, despite not ending with a newline. If the prompt doesn't appear, you can add a fflush(stdout); or fflush(0); after each of the prompting printf() statements.
The result of scanf() is checked to deal with EOF.
The format of scanf() includes a leading space. This will skip white space before the character that's returned, so you get a non-blank, non-newline character.
The original condition action != 'i' || action != 'd' is always true; you need the && instead.
Nitpick: improve grammar of error message.
Note that after the loop, action might not be either i or d if the user triggered EOF (typed Control-D or equivalent). If you get EOF (for example, the user ran the program with standard input from /dev/null), you would not have a deterministic value in action except for the initialization to '\0'.
Here I fixed you code:
#include <stdio.h>
int main()
{
char action;
printf("Please enter 'i' to work with integers or 'd' to work with decimals.\n\n");
scanf("%c", &action);
while (action != 'i' && action != 'd') // here the loop will stop if action is 'i' or 'd'
{
printf("You didn't entered the right command. Please try again (i/d)\n");
scanf("\n%c", &action);// here to deal with '\n'
}
}
#include <stdio.h>
void main()
{
char ans='n';
do
{
printf("\n Enter yes or no:");
scanf("%c",ans);
printf("\n entered %c",ans);
}while(ans == 'y');
}
As do while the loop is getting exccuted and that scanf is working and prnting my answer (say my answer is y) , its coming for 2nd time but not doing the scan and getting exited . May i know the reason for this ? why it is happening and what is the correct way to handle the infinite loop.
First up, you're missing a & in the scanf:
scanf("%c", &ans);
^
Second, you're not handling the newline, and the %c format specifier doesn't ignore blanks. So you read a character, press return, and the next scanf is immediately satisfied by that \n. To ignore blanks in scanf try:
scanf(" %c", &ans);
^
Not only are you missing the &address-of operator as indicated in other answers, but you're also missing the return value checks. Consider if a user presses CTRL+Z in Windows, or CTRL+d in Linux, to close stdin. Your loop would run infinitely and freeze your app ;)
if (scanf("%c", &ans) != 1) {
break;
}
Alternatively, I would suggest using getchar because it's far cleaner:
int main(void) { /* NOTE: There is no "void main()" entrance point in C. main should always return 'int'. */
int c;
do {
c = getchar();
} while (c == 'y');
return 0;
}
Use fflush(stdin) to flush those return feeds.
But when you are inputting a single character, then why not use getchar()?
EDIT:
As correctly pointed out by cnicutar here, fflush(stdin) has undefined behaviour. There doesn't seem to be any inbuilt function to take care of that and hence must be taken care of in the code itself.
One example could be:
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
Thanks for pointing that out there!