Reading spaces with scanf - c

printf("Type first name:"); scanf("%[^\n]%*c",msg);
printf("Type last name: "); scanf("%[^\n]%*c",aux2);
....
printf("Type adress:"); scanf("%[^\n]%*c",aux2);
....
printf("Type phone:"); scanf("%[^\n]%*c",aux2);
I want to read some string with spaces.
But scanf here has no effect..
After running this,I get:"Type first name:Type last name:Type adress:Type phone:")
Also ,I use in my code scanf("%c",&c)` to read some chars...
What's the problem here,why I can't read those string?
*edited

It's still not obvious what your problem is (to me, anyway), but if you want to read a line of text including spaces, fgets is probably the easiest solution.
char buf[100];
fgets(buf, sizeof(buf), stdin);
Note that fgets will stop reading once it encounters the \n character but it will append it to your buffer.

It seems that a \n character (which probably came from previous inputs) is in the input stream(stdin) when execution of the program reaches the scanfs which you posted.
scanf("%[^\n]%*c",aux2);
will not scan \n if it is the next character in the stdin and fails.To fix it,just add a
getchar();
just before the first scanf. This will gobble up the trailing \n from the stdin.

Related

A do-while loop keeps saying the same thing [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 4 years ago.
If I try something such as:
int anint;
char achar;
printf("\nEnter any integer:");
scanf("%d", &anint);
printf("\nEnter any character:");
scanf("%c", &achar);
printf("\nHello\n");
printf("\nThe integer entered is %d\n", anint);
printf("\nThe char entered is %c\n", achar);
It allows entering an integer, then skips the second scanf completely, this is really strange, as when I swap the two (the char scanf first), it works fine. What on earth could be wrong?
When reading input using scanf, the input is read after the return key is pressed but the newline generated by the return key is not consumed by scanf, which means the next time you read a char from standard input there will be a newline ready to be read.
One way to avoid is to use fgets to read the input as a string and then extract what you want using sscanf as:
char line[MAX];
printf("\nEnter any integer:");
if( fgets(line,MAX,stdin) && sscanf(line,"%d", &anint)!=1 )
anint=0;
printf("\nEnter any character:");
if( fgets(line,MAX,stdin) && sscanf(line,"%c", &achar)!=1 )
achar=0;
Another way to consume the newline would be to scanf("%c%*c",&anint);. The %*c will read the newline from the buffer and discard it.
You might want to read this:
C FAQ : Why does everyone say not to use scanf?
The other answers are correct - %c does not skip whitespace. The easiest way to make it do so is to place whitespace before the %c:
scanf(" %c", &achar);
(Any whitespace in the format string will make scanf consume all consecutive whitespace).
It doesn't skip the second scanf(); the second scanf() reads the newline left behind by the first scanf(). Most format codes skip white space; the %c format does not skip white space.
calling getchar() before scanf will also purge the stored line break. More lightweight but more situational
char input_1;
char input_2;
getchar();
scanf("%c", &input_1);
getchar();
scanf("%c", &input_2);
will flush the line breaks, more useful in consecutive lines of code where you know it's only one queued value and not a string
Try also _flushall() after each printf call. . Basically, by default MS’s C++ buffers stream output, and the the flushing causes the output stream to empty.

Appending a character and a string variable to a file in CSV format C programming [duplicate]

I have the following program:
int main(int argc, char *argv[])
{
int a, b;
char c1, c2;
printf("Enter something: ");
scanf("%d", &a); // line 1
printf("Enter other something: ");
scanf("%d", &b); // line 2
printf("Enter a char: ");
scanf("%c", &c1); // line 3
printf("Enter another char: ");
scanf("%c", &c2); // line 4
printf("Done"); // line 5
system("PAUSE");
return 0;
}
As I read in the C book, the author says that scanf() left a newline character in the buffer, therefore, the program does not stop at line 4 for user to enter the data, rather it stores the new line character in c2 and moves to line 5.
Is that right?
However, does this only happen with char data types? Because I did not see this problem with int data types as in line 1, 2, 3. Is it right?
The scanf() function skips leading whitespace automatically before trying to parse conversions other than characters. The character formats (primarily %c; also scan sets %[…] — and %n) are the exception; they don't skip whitespace.
Use " %c" with a leading blank to skip optional white space. Do not use a trailing blank in a scanf() format string.
Note that this still doesn't consume any trailing whitespace left in the input stream, not even to the end of a line, so beware of that if also using getchar() or fgets() on the same input stream. We're just getting scanf to skip over whitespace before conversions, like it does for %d and other non-character conversions.
Note that non-whitespace "directives" (to use POSIX scanf terminology) other than conversions, like the literal text in scanf("order = %d", &order); doesn't skip whitespace either. The literal order has to match the next character to be read.
So you probably want " order = %d" there if you want to skip a newline from the previous line but still require a literal match on a fixed string, like this question.
Use scanf(" %c", &c2);. This will solve your problem.
Another option (that I got from here) is to read and discard the newline by using the assignment-supression option. To do that, we just put a format to read a character with an asterisk between % and c:
scanf("%d%*c",&a); // line 1
scanf("%c%*c",&c1); // line 3
scanf will then read the next char (that is, the newline) but not assign it to any pointer.
In the end, however, I would second the FAQ's last option:
Or, depending on your requirements, you could also forget about scanf()/getchar(), use fgets() to get a line of text from the user and parse it yourself.
To echo what I have posted in another answer about C++: I suggest to toss scanf() away, to never use it, and to instead use fgets() and sscanf().
The reason for this is, that at least in Unix-like systems by default, the terminal your CLI program runs on does some processing of the user input before your program sees it. It buffers input until a newline is entered, and allows for some rudimentary line editing, like making backspace work.
So, you can never get a single character at a time, or a few single characters, just a full line. But that's not what e.g. scanf("%d") processes, instead it processes just the digits, and stops there, leaving the rest buffered in the C library, for a future stdio function to use. If your program has e.g.
printf("Enter a number: ");
scanf("%d", &a);
printf("Enter a word: ");
scanf("%s", word);
and you enter the line 123 abcd, it completes both scanf()s at once, but only after a newline is given. The first scanf() doesn't return when a user has hit space, even though that's where the number ends (because at that point the line is still in the terminal's line buffer); and the second scanf() doesn't wait for you to enter another line (because the input buffer already contains enough to fill the %s conversion).
This isn't what users usually expect!
Instead, they expect that hitting enter completes the input, and if you hit enter, you either get a default value, or an error, with possibly a suggestion to please really just give the answer.
You can't really do that with scanf("%d"). If the user just hits enter, nothing happens. Because scanf() is still waiting for the number. The terminal sends the line onward, but your program doesn't see it, because scanf() eats it. You don't get a chance to react to the user's mistake.
That's also not very useful.
Hence, I suggest using fgets() or getline() to read a full line of input at a time. This exactly matches what the terminal gives, and always gives your program control after the user has entered a line. What you do with the input line is up to you, if you want a number, you can use atoi(), strtol(), or even sscanf(buf, "%d", &a) to parse the number. sscanf() doesn't have the same mismatch as scanf(), because the buffer it reads from is limited in size, and when it ends, it ends -- the function can't wait for more.
(fscanf() on a regular file can also be fine if the file format is one that supports how it skims over newlines like any whitespace. For line-oriented data, I'd still use fgets() and sscanf().)
So, instead of what I had above, use something like this:
printf("Enter a number: ");
fgets(buf, bufsize, stdin);
sscanf(buf, "%d", &a);
or, actually, check the return value of sscanf() too, so you can detect empty lines and otherwise invalid data:
#include <stdio.h>
int main(void)
{
const int bufsize = 100;
char buf[bufsize];
int a;
int ret;
char word[bufsize];
printf("Enter a number: ");
fgets(buf, bufsize, stdin);
ret = sscanf(buf, "%d", &a);
if (ret != 1) {
fprintf(stderr, "Ok, you don't have to.\n");
return 1;
}
printf("Enter a word: ");
fgets(buf, bufsize, stdin);
ret = sscanf(buf, "%s", word);
if (ret != 1) {
fprintf(stderr, "You make me sad.\n");
return 1;
}
printf("You entered %d and %s\n", a, word);
}
Of course, if you want the program to insist, you can create a simple function to loop over the fgets() and sscanf() until the user deigns to do what they're told; or to just exit with an error immediately. Depends on what you think your program should do if the user doesn't want to play ball.
You could do something similar e.g. by looping over getchar() to read characters until a newline after scanf("%d") returned, thus clearing up any garbage left in the buffer, but that doesn't do anything about the case where the user just hits enter on an empty line. Anyway, fgets() would read until a newline, so you don't have to do it yourself.
Use getchar() before calling second scanf().
scanf("%c", &c1);
getchar(); // <== remove newline
scanf("%c", &c2);
Two workarounds. One is catch the extra whitespace trickly.
getchar(); // (1) add `getchar()`
scanf("%c", &c1);
scanf(" %c", &c1); // (2) add whitespace before %c
The other is using fgets() to instead scanf(). Note: gets() is unsafe, see why gets is dangerous
By contrast, I would prefer to recommend the second way. Because it's more readable and maintainable. For example, in first way, you must think a while before adding/moving some scanf().
/*Take char input using scanf after int input using scanf just use fflush(stdin) function after int input */
#include<stdio.h>
#include<conio.h>
void main()
{
int x;
char y;
clrscr();
printf(" enter an int ");
scanf("%d",&x);
fflush(stdin);
printf("\n Now enter a char");
scanf("%c",&y);
printf("\n X=%d and Y=%c",x,y);
getch();
}

C - While loop runs infinitively after using a getch() [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 4 years ago.
If I try something such as:
int anint;
char achar;
printf("\nEnter any integer:");
scanf("%d", &anint);
printf("\nEnter any character:");
scanf("%c", &achar);
printf("\nHello\n");
printf("\nThe integer entered is %d\n", anint);
printf("\nThe char entered is %c\n", achar);
It allows entering an integer, then skips the second scanf completely, this is really strange, as when I swap the two (the char scanf first), it works fine. What on earth could be wrong?
When reading input using scanf, the input is read after the return key is pressed but the newline generated by the return key is not consumed by scanf, which means the next time you read a char from standard input there will be a newline ready to be read.
One way to avoid is to use fgets to read the input as a string and then extract what you want using sscanf as:
char line[MAX];
printf("\nEnter any integer:");
if( fgets(line,MAX,stdin) && sscanf(line,"%d", &anint)!=1 )
anint=0;
printf("\nEnter any character:");
if( fgets(line,MAX,stdin) && sscanf(line,"%c", &achar)!=1 )
achar=0;
Another way to consume the newline would be to scanf("%c%*c",&anint);. The %*c will read the newline from the buffer and discard it.
You might want to read this:
C FAQ : Why does everyone say not to use scanf?
The other answers are correct - %c does not skip whitespace. The easiest way to make it do so is to place whitespace before the %c:
scanf(" %c", &achar);
(Any whitespace in the format string will make scanf consume all consecutive whitespace).
It doesn't skip the second scanf(); the second scanf() reads the newline left behind by the first scanf(). Most format codes skip white space; the %c format does not skip white space.
calling getchar() before scanf will also purge the stored line break. More lightweight but more situational
char input_1;
char input_2;
getchar();
scanf("%c", &input_1);
getchar();
scanf("%c", &input_2);
will flush the line breaks, more useful in consecutive lines of code where you know it's only one queued value and not a string
Try also _flushall() after each printf call. . Basically, by default MS’s C++ buffers stream output, and the the flushing causes the output stream to empty.

Reading newline from previous input when reading from keyboard with scanf()

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

Simple C scanf does not work? [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 4 years ago.
If I try something such as:
int anint;
char achar;
printf("\nEnter any integer:");
scanf("%d", &anint);
printf("\nEnter any character:");
scanf("%c", &achar);
printf("\nHello\n");
printf("\nThe integer entered is %d\n", anint);
printf("\nThe char entered is %c\n", achar);
It allows entering an integer, then skips the second scanf completely, this is really strange, as when I swap the two (the char scanf first), it works fine. What on earth could be wrong?
When reading input using scanf, the input is read after the return key is pressed but the newline generated by the return key is not consumed by scanf, which means the next time you read a char from standard input there will be a newline ready to be read.
One way to avoid is to use fgets to read the input as a string and then extract what you want using sscanf as:
char line[MAX];
printf("\nEnter any integer:");
if( fgets(line,MAX,stdin) && sscanf(line,"%d", &anint)!=1 )
anint=0;
printf("\nEnter any character:");
if( fgets(line,MAX,stdin) && sscanf(line,"%c", &achar)!=1 )
achar=0;
Another way to consume the newline would be to scanf("%c%*c",&anint);. The %*c will read the newline from the buffer and discard it.
You might want to read this:
C FAQ : Why does everyone say not to use scanf?
The other answers are correct - %c does not skip whitespace. The easiest way to make it do so is to place whitespace before the %c:
scanf(" %c", &achar);
(Any whitespace in the format string will make scanf consume all consecutive whitespace).
It doesn't skip the second scanf(); the second scanf() reads the newline left behind by the first scanf(). Most format codes skip white space; the %c format does not skip white space.
calling getchar() before scanf will also purge the stored line break. More lightweight but more situational
char input_1;
char input_2;
getchar();
scanf("%c", &input_1);
getchar();
scanf("%c", &input_2);
will flush the line breaks, more useful in consecutive lines of code where you know it's only one queued value and not a string
Try also _flushall() after each printf call. . Basically, by default MS’s C++ buffers stream output, and the the flushing causes the output stream to empty.

Resources