printf("Enter 'a' : "); runs 2 times after 1st loop - c

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;
}

Related

entering a phrase to scanf("%c", &ch)... (%c for sequence, not for single symbol)

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.

Program to replace a letter with another in C

I wrote a program to replace a letter in a string. Although it has no error, the output is not as expected. Please help me with it.
#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<string.h>
void replace(char s,char d);
char a[100];
int main()
{
char b,r;
printf("enter the string\n:");
gets(a);
printf("enter the the letter to be replaced\n:");
scanf("%c", &b);
printf("enter the letter to be replaced with\n:");
scanf("%c", &r);
replace(b,r);
}
void replace(char s, char d)
{
int i,f=0;
for (i = 0; a[i] != '\0'; i++)
{
if (a[i] == s)
{
a[i] = d;
f = 1;
}
}
if (f == 0)
{
printf("letter not found");
}
}
Output
enter the string
:hello every one
enter the the letter to be replaced
:e
enter the letter to be replaced with
:letter not found
I wanted to replace e with o but I am not able to give the input for word to be replaced
UPDATE
Use this loop to get rid of the input buffer problem when using scanf
but I am not sure how to implement it on my program need help
void
clear(void)
{
while ( getchar() != '\n' )
;
}
The scanf() function skips over initial whitespace characters when you read in strings using the %s specifier, but it does not do this when your read chars with the %c specifier. The gets() function that you use (which you should never ever ever use ever) reads through the newline, and discards it. So your first call to scanf() has a clean input stream. When you call scanf() the first time, a value is read into the variable b, but the trailing newline is left behind in the input stream. Then, when you try to read the next value, scanf() picks up this newline, instead of the value that you want to enter.
One fix for this is to discard any unwanted characters from the input stream like this:
while (getchar() != '\n')
continue; // discard unwanted characters
You can also test for the EOF character in the conditional expression if you really want to be careful. One virtue of this approach is that, no matter how many characters the user enters at your second prompt, only the first is taken, and the remaining characters through the newline are discarded. Since there is nothing left in the input stream, scanf() has to wait for the user to enter something at your third prompt. You should place this code after each call to scanf() to make sure that the input stream is clear.
Now, gets() is a terrible and unsafe function begging for buffer overflows, because it doesn't check to see if there is enough memory allocated for the string it is getting. Instead, use fgets(). This function takes an argument that specifies the maximum number of characters to read, including the null-terminator. fgets() also reads the newline character into the string, so you have to dispose of that yourself if you don't want it. Here are the modifications you need to make:
int i = 0;
...
char b,r;
printf("enter the string\n:");
fgets(a, 100, stdin);
while(a[i] != '\n' && a[i] != '\0') // remove newline
++i;
a[i] = '\0';
printf("enter the the letter to be replaced\n:");
scanf("%c", &b);
while (getchar() != '\n')
continue; // discard unwanted characters
printf("enter the letter to be replaced with\n:");
scanf("%c", &r);
while (getchar() != '\n')
continue; // discard unwanted characters
replace(b,r);
printf("%s\n", a);
...
I added a final printf() to display the changed string.

C: scanf doesn't work as I want

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;
}

for loop runs twice in C

I am new to C programming. And I was doing a practice, and the question goes like this: Use the ?: operator and the for statement to write a program that keeps taking the characters entered by the user until the character q is accounted.
And here is the program I wrote:
#include <stdio.h>
main()
{
int x, i=0;
for (x = 0; x == 'q'? 0 : 1; printf("Loop %d is finished\n",i))
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
x=getc(stdin);
putc(x,stdout);
++i;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}
The problem is: every time I enter a "non-q" character, the loop seems to run twice.
I don't know what is wrong with my program.
Please help!
When you enter a non-q letter, you also hit Enter, which is read in the second loop.
To make the loop only run once per input, use fgets() to read an entire line of input at once, and check if the input string matches your expectations.
When you type a and then press Enter, the newline character becomes part of the stdin stream. After a is read, the next time you execute x=getc(stdin), the value of x is set to \n. That's why two iterations of the loop get executed.
The loop runs twice because when you enter a non-q character, you actually enter two characters - the non-q character and the newline '\n' character. x = getc(stdin); reads the non-q character from the stdin stream but the newline is still lying in the buffer of stdin which is read in the next getc call.
You should use fgets to read a line from the stream as others have suggested and then you can process the line. Also, you should specify the return type of main as int. I suggest the following changes -
#include <stdio.h>
int main(void)
{
int x, i = 0;
// array to store the input line
// assuming that the max length of
// the line is 10. +1 is for the
// terminating null added by fscanf to
// mark the end of the string
char line[10 + 1];
for (x = 0; x == 'q'? 0 : 1; printf("Loop %d is finished\n", i))
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
// fgets reads an input line of at most
// one less than sizeof line, i.e.,
// 10 characters from stdin and saves it
// in the array line and then adds a
// terminating null byte
fgets(line, sizeof line, stdin);
// assign the first character of line to x
x = line[0];
putc(x, stdout);
++i;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}
When you enter a character, say 'x' and press enter, you actually input two characters, which are 'x' and '\n' also known as newline(when you hit enter). The '\n' becomes part of the input stream and the loop is executed for it as well.
Also, try inputting "xyz" and hit enter, the loop will be executed 4 times. For each 'x', 'y', 'z', and '\n'.
If you want the code to work one time for every input, use the function gets.
#include <stdio.h>
main()
{
int i=0;
char x[10];
for ( ; x[0]!='q'; printf("Loop %d is finished\n",i) )
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
gets(x);
i++;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}
In this code we declared x as an string, the gets() function reads the whole line we entered, then in the condition part of the for loop, we check whether the first character of the string is 'q' or not.

Error in storing char as variable from user input

the idea is that i type in a sentence and store it as a string... then i can choose a letter and change it to a different letter
int main(int argc, char *argv[])
{
char string[100];
char newLetter;
char oldLetter;
int i = 0;
printf("Please enter your sentence : ");
gets(string);
printf("\n\nWord is : %s" , string );
printf("\n\nTarget : ");
scanf("%s", &oldLetter);
printf("Replace with : ");
scanf("%s", &newLetter);
for ( i = 0; i < sizeof(string); i++)
{
if (string[i] == oldLetter)
{
string[i] = newLetter;
break;
}
}
printf("\n\nWord is : %s" , string );
system("PAUSE");
return 0;
}
any help in where I've gone wrong is appreciated
eg.
input could be - yellow lorry red lorry
then target - r
change to - t
output - yellow lotty ted lotty
Change the %s in the scanning of the two letters to %c and the code will run flawlessly.
First things first, since you are aiming to store a character to char oldLetter and char newLetter via scanf, you should be using the format specifier %c instead of the %s.
However, that won't be enough, because of the following: When you use functions like scanf or gets, you prompt user to input characters to the stdin stream. stdin stream is a buffered stream. You may think of it as a:
Stream of river that you;
drop characters into
each character you drop remains inside the river
until something takes them out
When scanf comes, and you type, say, A and then press the enter key, you put the following characters in the stream:
'A' '\n'
Where \n is the new-line character. With the enter key-press, you also inform the scanf that you're done. scanf then starts issuing the stdin buffer, let's see... 'A', a proper value for %c character. It takes that one out, leaves \n behind.
Then the next scanf comes, seeks for a %c in stream, finds the \n ready, takes that out. This is what you wouldn't want. Two ways to prevent it:
use fflush( stdin ); after the scanf calls, or
use while( getchar( ) != '\n' ); after the scanf calls
to dismiss/discard the remaining characters in the buffer.
And get rid of that break; if you want to replace each occurrence and not just the first one.
You can do it right, or you can do it wrong and hope that the person doesn't enter the right series of keystrokes or pipe in a file that doesn't end in newline, to break it ... up to you

Resources