I am using GCC to compile my C code.
My second scanf is not stopping to get the input.
It only reads in the first scanf and prints the two statements, one with what I entered in string and the other is just blank.
int main (void) {
setvbuf(stdout, NULL, _IONBF, 0);
char string[25] = {'\0'};
char c;
scanf(" %s", string);
scanf(" o%c", &out);
printf("Input is : %s \n\n", string);
printf("Out is: %c", out);
return 0;
}
Instead of getting
Input is whatever I typed and a prompt to enter a char for out
I got output as shown below
Input is : whatever i typed
Out is:
The program terminates. Can someone help. I've done some research and tried to put a space before %c for out and for string and still nothing happened.
You haven't defined out. And c is unused here. Having said that
Change
scanf(" o%c", &out); //What is that o in here? Is it a typo?
to
scanf(" %c", &out);
If your terminal uses line-buffered input
scanf(" %s", string);
can read the input till the first white-space. So the input buffer from the white-space is unused which is available for the next scanf which automatically starts reading from the buffer. So if you enter a string with spaces, the white-space will be assigned to the character out in your case
Change first scanf like below to clear the buffer:
if( scanf(" %s", string) == 1)
{
while(getchar()!='\n')
continue;
}
Also you might wish to replace
scanf(" %s", string);
with
fgets(string,25,stdin);
/* Use 26 if you actually wish to have max 25 characters
* ie char string[26]={'\0'}
*/
fgets has the advantage that it can read the white spaces and the newline charcter '\n' and it will automatically trim the output in case of an overflow.
Related
I'm trying to write a simple program to read an integer and then a string, then print both to standard output. Ideally, the execution should look something like this:
Input the number.
> 10
Input the string.
> a string
number: 10
string: a string
However, when I run the program, it freezes after the call to scanf() until more input is provided.
Input the number.
> 10
a string
Input the string.
>
number: 10
string: a string
Why is it waiting for input before fgets() is ever called?
#include <stdio.h>
int main()
{
int number;
char string[32];
printf("Input the number.\n> ");
scanf("%d\n", &number);
printf("\nInput the string.\n> ");
fgets(string, 32, stdin);
printf("\nnumber: %d\nstring: %s\n", number, string);
}
From a previous post...
https://stackoverflow.com/a/5918223/2203541
#include <stdio.h>
int main()
{
int number;
int c;
char string[32];
printf("Input the number.\n> ");
scanf("%d", &number);
do
{
c = getchar();
} while (c != '\n');
printf("\nInput the string.\n> ");
fgets(string, 32, stdin);
printf("\nnumber: %d\nstring: %s\n", number, string);
}
"Why is fgets waiting for input before it's even called"
fgets() does not act until it is called, but if when called, and if pointing to stdin and there is content remaining in the stdin stream, it will consume it immediately. If that contents contained EOF, n-1, OR a newline (read link) execution flow will continue.
The problem here is that scanf() (called prior to fgets()) is notorious for doing exactly what it is asked to do. For example, upon user entering 12<return> two recognizable items are entered into stdin, digits and a newline but by using "%d" as the format specifier, only the first of those items is consumed, leaving the \n hanging, until the very next call to fgets(), which accepts it as input, allowing execution flow to resume immediately (as described above), causing the apparent skip you are seeing.
[This is one (of several) examples that will provide a work around for the scanf() issue:
Change this:
printf("Input the number.\n> ");
scanf("%d", &number);//leaves the newline
To this:
char c;
...
printf("Input the number.\n> ");
scanf("%d%c", &number, &c);//consumes the newline
From comments:
"is there a way to use fgets to read an integer"
Yes, I prefer fgets() coupled with your favorite string to number converter. (There are several) The simplest is this:
char cNum[10];
int num;
printf("Input the number.\n> ");
if(fgets(cNum, sizeof cNum, stdin))
{
num = atoi(cNum);
}
else //handle error
See also strtol() for a more robust solution.
Alright, so I played around with it some more and did a little more studying on scanf() format syntax, and figured out a solution. Apparently, putting the whitespace character at the end of my scanf call there tells it to keep reading until it finds something AFTER the whitespace, so of course it would hang up there until you give more input.
Remove the whitespace character in the scanf formatter, and add a leading space to the following scanf call.
The reason I had used fgets originally was so I could specify a buffer length to avoid overflow. Apparently, the same effect can be achieved using %32s in the scanf call. The fixed code looks like this:
#include <stdio.h>
int main()
{
int number;
char string[32];
printf("Input the number.\n> ");
scanf("%d", &number);
printf("\nInput the string.\n> ");
scanf(" %32s", &string);
printf("\nnumber: %d\nstring: %s\n", number, string);
}
I'm trying to read a whole line using scanf multiple times and for some reasons it only works the first time.
The second time the loop runs the compiler ignores the scanf function
Here is my code:
#include <stdio.h>
int main()
{
char msg[100];
char to[100];
while (1)
{
printf("[]:Msg to ? :");
scanf("%s", to);
printf("[]:Msg: ");
scanf("%99[^.]", msg);
printf("Sending %s\n", msg);
}
return 0;
}
And this is the output Im given:
[]:Msg to ? :Him []:Msg: Hello mister him!. Sending Hello mister
him! []:Msg to ? :[]:Msg:
And here I was expecting to be able to change the variable to ...
Adding a space before %s for some reason has no effect here
The problem is here:
scanf("%99[^.]", msg);
This statement reads up to 99 characters, but only until the next non-matching character. Now if you put
Hello mister him!.
into the input buffer, you indeed have
"Hello mister him!.\n"
in the stdin input stream buffer. Now, the scanf processes everything up to (but not including) the dot, so the dot and the newline remains in the input buffer. The next call to scanf()
scanf("%s", to);
now fetches the dot and the newline from the output buffer, which automatically concludes the next line to read. Now the input buffer is empty and the following scanf waits for the next message.
To fix this, you can skip the dot and the newline like this:
scanf("%99[^.]", msg);
getchar(); // Pacman (Eat the dot)
and in the other scanf use
// scanf(" %s", to); // Skip the preceding newline
(this is unnecessary, as H.S. pointed out)
Please note, that the case of an input message >99 chars is not handled properly yet.
If you wants to read a whole line using scanf you can use %[^\n] instead of %99[^.]. And make sure to add a getchar() if any 'enter' is pressed just before scanning with %[^\n].
The changes showed in the code bellow may be useful:
while (1)
{
printf("[]:Msg to ? :");
scanf("%[^\n]", to);
getchar();
printf("[]:Msg: ");
scanf("%[^\n]", msg);
getchar();
printf("Sending %s\n", msg);
}
This is simple code. In which I am taking a input, printing it, and taking again and printing it once more.
For the second time it doesn't let me give the input.
Can someone explain why ?
#include "stdio.h"
int main()
{
char buff[50];
printf("Enter a String\n");
scanf("%[^\n]s",buff);
puts(buff);
printf("Enter another String\n");
scanf("%[^\n]s",buff);
puts(buff);
return 0;
}
Output :
Enter a String
Hello // This I have entered
Hello // This is the output
Enter another String
Hello // This I haven't entered, It automatically takes this.
In the second scanf(), place a space at the beginning of your input specifier:
scanf(" %[^\n]s",buff);
^^^
This will eat the character that is currently satisfying scanf the second time, and allow you to enter a second string.
Using a different format helps
// scanf("%[^\n]s",buff);
scanf(" %49[^\n]",buff);
// ^ no s
// ^ width limit
// ^ consume previous line's leftover \n (and all white-space)
Note that scanf(" %[^\n]",buff); does not change buff when user enters only " \n".
But better to use fgets()
fgets(buff, sizeof buff, stdin);
buf[strcspn(buffer, "\n")] = 0; // to remove \n
This was supposed to be very simple, but I'm having trouble to read successive inputs from the keyboard.
Here's the code:
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
scanf ("%s", string);
printf ("%s", string);
printf ("\nwrite a character: ");
scanf ("%c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
What is happening
When I enter a string (e.g.: computer), the program reads the newline ('\n') and puts it in character. Here is how the display looks like:
write something: computer
computer
Character:
Correspondent number: 10
Moreover, the program does not work for strings with more than one word.
How could I overcome these problems?
First scanf read the entered string and left behind \n in the input buffer. Next call to scanf read that \n and store it to character.
Try this
scanf (" %c", &characte);
// ^A space before %c in scanf can skip any number of white space characters.
Program will not work for strings more than one character because scanf stops reading once find a white space character. You can use fgets instead
fgets(string, 200, stdin);
OP's first problem is typically solved by prepending a space to the format. This will consume white-space including the previous line's '\n'.
// scanf("%c", &character);
scanf(" %c", &character);
Moreover, the program does not work for strings with more than one word. How could I overcome these problems?
For the the 2nd issue, let us go for a more precise understanding of "string" and what "%s" does.
A string is a contiguous sequence of characters terminated by and including the first null character. 7.1.1 1
OP is not entering a string even though "I enter a string (e.g.: computer)," is reported. OP is entering a line of text. 8 characters "computer" followed by Enter. There is no "null character" here. Instead 9 char "computer\n".
"%s" in scanf("%s", string); does 3 things:
1) Scan, but not save any leading white-space.
2) Scan and save into string any number of non-white-space.
3) Stop scanning when white-space or EOF reached. That char is but back into stdin. A '\0' is appended to string making that char array a C string.
To read a line including spaces, do not use scanf("%s",.... Consider fgets().
fgets(string, sizeof string, stdin);
// remove potential trailing \r\n as needed
string[strcspn(string, "\n")] = 0;
Mixing scanf() and fgets() is a problem as calls like scanf("%s", string); fgets(...) leave the '\n' in stdin for fgets() to read as a line consisting of only "\n". Recommend instead to read all user input using fgets() (or getline() on *nix system). Then parse the line read.
fgets(string, sizeof string, stdin);
scanf(string, "%c", &character);
If code must user scanf() to read user input including spaces:
scanf("%*[\n]"); // read any number of \n and not save.
// Read up to 199 `char`, none of which are \n
if (scanf("%199[^\n]", string) != 1) Handle_EOF();
Lastly, code should employ error checking and input width limitations. Test the return values of all input functions.
What you're seeing is the correct behavior of the functions you call:
scanf will read one word from the input, and leave the input pointer immediately after the word it reads. If you type computer<RETURN>, the next character to be read is the newline.
To read a whole line, including the final newline, use fgets. Read the documentation carefully: fgets returns a string that includes the final newline it read. (gets, which shouldn't be used anyway for a number of reasons, reads and discards the final newline.)
I should add that while scanf has its uses, using it interactively leads to very confusing behavior, as I think you discovered. Even in cases where you want to read word by word, use another method if the intended use is interactive.
You can make use of %*c:
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
scanf ("%s%*c", string);
printf ("%s", string);
printf ("\nwrite a character: ");
scanf ("%c%*c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
%*c will accept and ignore the newline or any white-spaces
You cal also put getchar() after the scanf line. It will do the job :)
The streams need to be flushed. When performing successive inputs, the standard input stream, stdin, buffers every key press on the keyboard. So, when you typed "computer" and pressed the enter key, the input stream absorbed the linefeed too, even though only the string "computer" was assigned to string. Hence when you scanned for a character later, the already loaded new line character was the one scanned and assigned to character.
Also the stdout streams need to be flushed. Consider this:
...
printf("foo");
while(1)
{}
...
If one tries to execute something like this then nothing is displayed on the console. The system buffered the stdout stream, the standard output stream, unaware of the fact it would be encounter an infinite loop next and once that happens, it never gets a chance to unload the stream to the console.
Apparently, in a similar manner whenever scanf blocks the program and waits on stdin, the standard input stream, it affects the other streams that are buffering. Anyway, whatsoever may be the case it's best to flush the streams properly if things start jumbling up.
The following modifications to your code seem to produce the desired output
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
fflush(stdout);
scanf ("%s", string);
fflush(stdin);
printf ("%s", string);
printf ("\nwrite a character: ");
fflush(stdout);
scanf ("%c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
Output:
write something: computer
computer
write a character: a
Character a Correspondent number: 97
I need to use scanf to get a character and a string which would store the user's answer. (yes/no)
The code below skips scanf("%c", &elem).
while ( !strcmp ("yes", option))
{
printf("enter the elements \n\n");
elem=getchar();
printf("you have entered %c\n",elem);
enqueue(st, elem);
printf("please enter yes or no ");
scanf("%s[^\n]",option);
}
./out
enter the elements
a
you have entered a
enqueue elem= a
please enter yes or no yes
enter the elements
you have entered
enqueue elem=
You don't have any scanf("%c", &elem) in your code... btw the problem is with the enter for scanf. When you get an input by scanf, an enter character stays in the input buffer which will be read by your getchar() function in the second round. one simple way to solve it is to add a dummy getchar after your scanf line:
while ( !strcmp ("yes",option))
{
printf("enter the elements \n\n");
elem=getchar();
printf("you have entered %c\n",elem);
enqueue(st,elem);
printf("please enter yes or no ");
scanf("%s[^\n]",option);
getchar();
}
You can find more information about how to clear your input buffer here: How to clear input buffer in C?
I can recommend you consider two things:
For getting only a character, I personally found it much more easier to use getch and getche function in Windows, and equivalent of them for GCC-compatible environments. You can find samples of it online or on this line [What is Equivalent to getch() & getche() in Linux?
Always flush the input buffer after you read your input to prevent any similar problems to happen.
The input functions check the input buffer, which you can find at 0xb8000000, and check the first input there. If the buffer is empty, they wait for the user to enter the input, otherwise, they check the first element in the buffer and then examine that to what they expect to read. If they succeed, they read it and remove it from buffer. Otherwise, they fail to give you your input and depending on the function, the result is different.
For Example, consider the following line:
scanf("%d %d %f", &a, &b &c);
and give the input as:
a 2 4
The scanf will return 0, which means it reads zero inputs so 'a', 2, and 4 remains in your buffer. So your buffer looks like: [a, 2, 4]. As a result if you add the following line:
scanf("%c", &ch);
scanf will try to get a character from the buffer, and it reads character 'a' and put it in variable ch. So it doesn't get any input from user. And you end up with having 2 and 4 on your buffer again.
When you are pressing Enter/Return key to enter the element then a \n character is also passed to the buffer along with the element. This \n is read by your getchar on next call.
To consume this \n place this line after the getchar();
int ch;
while((ch = getchar()) != EOF && ch != '\n');
Take care mixing scanf() format specifiers "%c", "%s" and "%[]".
Correct usage of "%[^\n]": there is no s. If leading whitespace in not wanted to be saved, include a leading space as in " %[^\n]"
char option[100];
// scanf("%s[^\n]", option);
scanf(" %[^\n]", option);
// or better
scanf(" %99[^\n]", option);
// or pedantic
switch (scanf(" %99[^\n]", option)) {
case EOF: HandleEOForIOError(); break;
case 0: HandleNoData(); break; // might not be possible here.
case 1: HandleSuccess();
Correct usage of "%c". If leading whitespace in not wanted to be save, include a leading space as in " %c". This may be the case in OP's code so the preceding inputs Enter or '\n' is consumed.
char elem;
scanf(" %c", &elem);
Correct usage of "%s". Leading whitespace is not saved with or without a leading space.
char option[100];
scanf("%99s", option);
// Following works the same.
scanf(" %99s", option);