I would like to use a character variable with scanf many times - c

In my program I must store input characters in variables and then add them to arrays. But is there a way to use the same variable each time?
char str1,str2;
printf("insert character");
scanf("%c",&str1);
printf("%c",str1);
printf("insert character");
scanf("%c",&str2);
printf("%c",str2);
I would like to do something like this but using one variable. Also can I use scanf more than 1 times? It seems the executable stops before the second character is given.

Yes, you can use scanf() more than once. Your problem is not actually because of scanf();, Its with your input, To give input for first scanf() in your program, what we naturally do is we type(through keyboard) a character and hit ENTER KEY,Under the hood when you hit ENTER KEY a '\n' character is produced which is read by your second scanf() ,that's why your second scanf() is not waiting for input from you as you expected, You need to clear this '\n' manually when you use %c.(when %d %f %s are used '\n' are automatically removed that's why we don't face this problem when using them).
To solve problem you can use "%c" like this " %c" (note space before %c, this skips '\n' characters)
scanf(" %c",&str1);
printf("%c",str1);
//code to add them to array's
scanf(" %c",&str1);//Have Re-Used the same variable str1.
printf("%c",str1);

Related

Using scanf() function two times: works in one case but not in other case [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
I'm the learning the very basics of C programming right now, and I'm practicing the scanf() function. This very, very simple program takes in a number and a letter and uses the printf() function to display the number and letter.
If I ask the user to enter the number first, the program works, i.e., asks for a number, asks for a letter, and prints the input. If I ask for the letter first, the program asks for a letter but then doesn't ask for a number.
I've tried multiple ways and reordered it, but it doesn't seem to work.
This works:
#include<stdio.h>
void main(){
int number;
char letter;
printf("Enter letter...");
scanf("%c", &letter);
printf("Enter number....");
scanf("%d", &number);
printf("Number entered: %d and letter entered: %c.\n", number, letter);
}
But, this combination doesn't work:
#include<stdio.h>
void main(){
int number;
char letter;
printf("Enter number....");
scanf("%d", &number);
printf("Enter letter...");
scanf("%c", &letter);
printf("Number entered: %d and letter entered: %c.\n", number, letter);
}
The output I get for the first program is:
Enter letter...a
Enter number....9
Number entered: 9 and letter entered: a.
Which is correct
But the second case doesn't work, and I don't get why it wouldn't work -- skips the "enter letter" part
the output is
Enter number....9
Enter letter...Number entered: 9 and letter entered:
.
Context: I entered "a" for letter and "9" for number in the above example.
It turns out there's a surprising difference between %d and %c. Besides the fact that %d scans potentially multiple digits while %c scans exactly one character, the surprising difference is that %d skips any leading whitespace, while %c does not.
And then there's another easily-overlooked issue when you're using scanf to read user inputs, which is, what happens to all those newlines -- the \n characters -- that get inserted when the user hits the ENTER key to input something?
So here's what happened. Your first program had
printf("Enter letter...");
scanf("%c", &letter);
printf("Enter number....");
scanf("%d", &number);
The user typed a letter, and ENTER, and a number, and ENTER. The first scanf call read the letter and nothing else. The \n stayed in the input stream. And then the second scanf call, with %d, skipped the \n (because \n is whitespace) and read the number, just like you wanted.
But in your second program you had the inputs in the other order, like this:
printf("Enter number....");
scanf("%d", &number);
printf("Enter letter...");
scanf("%c", &letter);
Now, the user types a number and hits ENTER, and the first scanf call reads the number and leaves the \n on the input stream. But then in the second scanf call, %c does not skip whitespace, so the "letter" it reads is the \n character.
The solution in this case is to explicitly force the whitespace-skipping that %c doesn't do by default. Another little-known fact about scanf is that a space in a format string doesn't mean "match one space character exactly", it means "match an arbitrary number of whitespace characters". So if you change your second program to:
printf("Enter number....");
scanf("%d", &number);
printf("Enter letter...");
scanf(" %c", &letter);
Now, the space character in " %c" in the second scanf call will skip over the \n that was left over after the user typed the number, and the second scanf call should read the letter it's supposed to.
Finally, a bit of editorializing. If you think this is a bizarre situation, if you think the exception to the way %c works is kind of strange, if you think it shouldn't have been this hard to read a number followed by a letter, if you think my explanation of what's going on has been far longer and more complicated than it ought to have been -- you're right. scanf is one of the uglier functions in the C Standard Library. I don't know any C programmers who use it for anything -- I don't believe I've ever used it. Realistically, its only use is for beginning C programmers to get data into their first programs, until they learn other, better ways of performing that task, ways that don't involve scanf.
So my advice to you is not to spend too much time trying to get scanf to work, or learning about all of its other foibles. (It has lots.) As soon as you're comfortable, start learning about the other, better ways of doing input, and leave scanf comfortably behind forever.
Try this
#include <stdio.h>
int main(void) {
int number;
char letter;
printf("Enter letter...");
scanf("%s", &letter);
printf("Enter number....");
scanf("%d", &number);
printf("Number entered: %d and letter entered: %c.\n", number, letter);
return 0;
}
If you change the %c to %s then you get the correct output.
Add a space before %c. So, change this:
scanf("%c", &letter);
to this:
scanf(" %c", &letter);
As I have written in caution when using scanf, this will make scanf eat the whitespaces and special characters (otherwise it will consider them as inputs).
Here, it will consume the newline character, on other words, the Enter you press, after typing your input!
To be exact, in your example, think of what the user (in this case you) do:
You type 9
You press Enter
You type 'a'
You press Enter
Now, when you input something, from your keyboard in this case, this will go into the Standard Input buffer, where it will patiently await to be read.
Here, scanf("%d", &number); will come and read a number. It finds 9 in the first cell of the STDIN buffer, it reads it, thus deleting it from the buffer.
Now, scanf("%c", &letter); comes, and it reads a character. It finds the newline character, that's the first Enter you pressed, and the function is now happy - it was told to read a character, and that's exactly what it did. Now that newline character gets deleted from the buffer (now what's left in there is 'a' and a newline character - these two are not going to be read, since there is no other function call. left for that).
So what changes if I write scanf(" %c", &letter); instead?
The first scanf will still read the number 9, and the buffer will now have a newline character, the 'a' character, and another newline character.
Now scanf(" %c", &letter);` is called, and it goes to search for a character to read in the STDIN buffer, only that now it will first consume any special characters found.
So there it goes to the buffer, it firstly encounters the newline character, it consumes it.
Then, it will encounter 'a', which is not a special character, and therefore it will read normally, and stored to the passed variable in scanf.
The last newline character will remain in the STDIN buffer, untouched and unseen, until the program terminates and the buffer gets deallocated.
Tip: You probably meant to write int main(void), instead of void main(). Read more in What should main() return in C and C++?
Specifying scanf the following way
scanf("%c", &letter);
does not skip white spaces and can read for example a new line character stored in the input buffer when the user pressed Enter entering previous data.
Use instead
scanf(" %c", &letter);
^^^
to skip white spaces.
From the C Standard (7.21.6.2 The fscanf function)
8 Input white-space characters (as specified by the isspace function)
are skipped, unless the specification includes a [, c, or n specifier.
and
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.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main(void)
From the C Standard (5.1.2.2.1 Program startup)
1 The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }

Variable scanf inputs

How exactly would you deal with having a variable amount of scanf inputs?
I'm scanning commands, some of them are 1. word commands but some require numeric argument. Does scanf allow the following?
scanf(" %s %d", command, argument);
Would that ignore the "argument" if only one value was inputed?
The other option i though of was
scanf(" %s", command)
if (strcmp(command, "somethin") {
scanf("%d", argument); }
But that would create a newline right? the terminal has to recieve the input in form of "> command argument"
SO, my question is, how to solve the problem of having variable number of inputs.
No, it won't "create a newline". scanf is completely unaware of any newlines. scanf treats the input stream as a linear sequence of data separated by whitespace. Newline is just whitespace, no different from any other whitespace. The only scanf format specifiers that can "see" newlines are %c and %[]. Your %s and %d are completely newline-agnostic.
Which means that your second example is doing it right (within the natural limitations of scanf). It won't "create a newline". It will read a single line, if you supply the input in a single line (like somethin 42).
You might actually run into the "opposite" problem: if the user forgets to input the required argument in a single line, the next scanf will wait for it on the next line. And on the next line. And on the next line... until he user finally supplies it. I'm not sure this behavior is desirable for you. If not, then a better idea would be to use dedicated line-based input through fgets and then parse the line manually.
P.S. There's no reason to prepend %s and %d with spaces.

C skips user input from subsequent scanf statement [duplicate]

I've been having a lot of problems trying to figure out how to use scanf(). It seems to work fine with integers, being fairly straight forward scanf("%d", &i).
Where I am running into issues is using scanf() in loops trying to read input. For example:
do {
printf("counter: %d: ", counter);
scanf("%c %c%d", &command, &prefix, &input);
} while (command != 'q');
When I enter in a validly structured input like c P101, it seems to loop again before prompting me. This seems to happen even with a single:
scanf("%c", &c)
in a while loop. It'll do the loop twice before prompting me again. What is making it loop twice, and how do I stop it?
When I enter in less amount of input that programmatically wouldn't have another character or number such as q, pressing enter seems to prompt me to enter more. How do I get scanf() to process both single and double character entries?
When you enter "c P101" the program actually receives "c P101\n". Most of the conversion specifiers skip leading whitespace including newlines but %c does not. The first time around everything up til the "\n" is read, the second time around the "\n" is read into command, "c" is read into prefix, and "P" is left which is not a number so the conversion fails and "P101\n" is left on the stream. The next time "P" is stored into command, "1" is stored into prefix, and 1 (from the remaining "01") is stored into input with the "\n" still on the stream for next time. You can fix this issue by putting a space at the beginning of the format string which will skip any leading whitespace including newlines.
A similiar thing is happening for the second case, when you enter "q", "q\n" is entered into the stream, the first time around the "q" is read, the second time the "\n" is read, only on the third call is the second "q" read, you can avoid the problem again by adding a space character at the beginning of the format string.
A better way to do this would be to use something like fgets() to process a line at a time and then use sscanf() to do the parsing.
It's really broken! I didn't know it
#include <stdio.h>
int main(void)
{
int counter = 1;
char command, prefix;
int input;
do
{
printf("counter: %d: ", counter);
scanf("%c %c%d", &command, &prefix, &input);
printf("---%c %c%d---\n", command, prefix, input);
counter++;
} while (command != 'q');
}
counter: 1: a b1
---a b1---
counter: 2: c d2
---
c1---
counter: 3: e f3
---d 21---
counter: 4: ---e f3---
counter: 5: g h4
---
g3---
The output seems to fit with Robert's answer.
Once you have the string that contains the line. i.e. "C P101", you can use the parsing abilities of sscanf.
See:
http://www.cplusplus.com/reference/clibrary/cstdio/sscanf.html
For question 1, I suspect that you've got a problem with your printf(), since there is no terminating "\n".
The default behavior of printf is to buffer output until it has a complete line. That is unless you explicitly change the buffering on stdout.
For question 2, you've just hit one of the biggest problems with scanf(). Unless your input exactly matches the scan string that you've specified, your results are going to be nothing like what you expect.
If you've got an option you'll have better results (and fewer security issues) by ignoring scanf() and doing your own parsing. For example, use fgets() to read an entire line into a string, and then process the individual fields of the string — maybe even using sscanf().
Perhaps using a while loop, not a do...while loop will help. This way the condition is tested before execution of the code.
Try the following code snippet:
while(command != 'q')
{
//statements
}
Also, if you know the string length ahead of time, 'for' loops can be much easier to work with than 'while' loops. There are also some trickier ways to dynamically determine the length as well.
As a final rant: scanf() does not "suck." It does what it does and that is all.
The gets() function is very dangerous (though convenient for no-risk applications), since it does not natively do any checking of the input. It is VERY commonly known as a point of exploit, specifically buffer overflow attacks, overwriting space in registers not allocated for that variable. Therefore if you choose to use it, spend some time putting some solid error checking/correction in.
However, almost invariably, either fgets() or POSIX getline() should be used to read the line — noting that the functions both include the newline in the input string, unlike gets(). You can remove the trailing newline from string read by either fgets() or getline() using string[strcspn(string, "\n")] = '\0'; — this works reliably.

Storing inputted characters in an array

I have to enter chars in C. Input is of the form:
'f' 'g'
'd' 'b'
'2' '3'
Each line has a pair of two characters, and my task is to store them in two different arrays. One array will store {'f','d','2'} and the other will store {'g','b','3'}.
My code is this:
for(i=0;i<n;i++){
scanf(" %c",&arr1[i]);
scanf("%c",&arr2[i]);
}
where n is the no. of rows.
There is no error but no values are stored in the second array.
Your code looks fine except you need space before %c in second scanf too:
for(i=0;i<n;i++){
scanf(" %c",&arr1[i]);
scanf(" %c",&arr2[i]);
}
A space before %c in scanf can skip any number of white-spaces. In absence of it, second scanf reads the white-spaces and store that in arr2.
==> Live Demo.
If your input is f, you press enter, and then g - then your second scanf call will consume the new line between the letters.
scanf("%c", ... Will read next character (this includes white space so it may read blank character).
scanf(" %c", ... Will skip white-space and read in next non-white-space character.
Note: New lines ('\n') are also considered white-space.
I mean, since you've told us that the input is of form like you've shown to us, there apparently are 's and spaces to be discarded. If so, it is almost as if you have to parse an input...
If you are certain that the input will be of the form you've described, then one way to do it would be to:
Read and discard until the first single-quote, then also the single-quote
Read and store the following character
Read and discard the following single-quote
Do this once again
On each loop. What I have described above, could be achieved with the following block consisting of a single scanf call, where the format-string is the important part:
for ( ... ) {
scanf( "%*[^']'%c'%*[^']'%c'", &arr1[i], &arr2[i] );
}
This assumes that the input will be of the form as displayed on the question, with a single-character inside single-quotes, arbitrarily spaced, and like that.
%*[^']' part handles the first bullet on the list above
%c and the paired &arr1[i] does the second
' does the third
Rest does the fourth
I know that, as per asker's comment, that this is not what's being looked for, however I felt like there should at least be an answer addressing what the question says and not just what the asker thinks, with the hope that it helps anybody.

Difference between scanf("%c", &c) and scanf(" %c", &c) [duplicate]

This question already has answers here:
Why does a space in my scanf statement make a difference? [duplicate]
(3 answers)
Closed 9 years ago.
Consider the following C code snippet:
#include <stdio.h>
int main()
{
int a;
char c;
scanf("%d",&a);
scanf("%c",&c);
printf("int=%d\n",a);
printf("char=%c\n",c);
}
I'm able to input only the integer and not the character.The output is simply the integer value and no value is output for the second printf statement.
However if I use a space before the format specifier:
scanf(" %c",&c);
It works as expected. Why is this the case?
Someone told me it has something to do with clearing the input buffer. Could someone shed some light on the same?
The difference between scanf("%c", &c1) and scanf(" %c", &c2) is that the format without the blank reads the next character, even if it is white space, whereas the one with the blank skips white space (including newlines) and reads the next character that is not white space.
In a scanf() format, a blank, tab or newline means 'skip white space if there is any to skip'. It does not directly 'clear the input buffer', but it does eat any white space which looks similar to clearing the input buffer (but is quite distinct from that). If you're on Windows, using fflush(stdin) clears the input buffer (of white space and non-white space characters); on Unix and according to the C standard, fflush(stdin) is undefined behaviour.
Incidentally, if you typed the integer followed immediately by a carriage return, the output of your program ends with two newlines: the first was in c and the second in the format string. Thus, you might have seen:
$ ./your_program
123
int=123
char=
$
That is, the scanf() reads the newline as its input. Consider an alternative input:
$ ./your_program
123xyz
int=123
char=x
$
The integer input stopped when it read the 'x'; the character input therefore reads the 'x'.
Because after you input the number and press ENTER, the new line stays in the buffer and will be processed by the second scanf.
In short, you saved new line in the variable c.
However ,if you use
scanf(" %c",&c);
// ^
the space will consume the new line, which makes c the value you expected.
You have to pass a pointer to the data object specified by the format string, so
scanf("%c", c);
will actually pass the value of c, which in turn could cause a program fault,
scanf("%c", &c);
will pass the address of c, allowing scanf to change the value of your copy.
The space after the %c will force it to look for a character, AND THEN a space. If there is not a space, it will not read the character

Resources