I cant use two scanf function to Enter the letters - c++

Why I cant use two scanf function to Enter the characters
for example
char a;
char b;
printf("a");
scanf("%c", &a);
printf("%c", a);
scanf("%c", &b);
printf("%c", b);
There are many solutions, but I want to know what is the reason why the2 scanf function does not work in characters

When you enter in a single character you're actually sending two characters to the program: the character you pressed and a newline character from when you pressed the Enter key.
Suppose you pressed "s" then Enter. The first scanf would read only the "s", leaving the newline in the input buffer. The second scanf will then immediately read the newline, which is then printed by the second printf.
If you entered two or more characters and pressed Enter, for example "abc" then Enter, the first scanf will read the "a" and the second scanf will immediately read the "b". The "c" and the newline will be left in the buffer when the program exits.

The procedure code of scanf is like that
scanf()
int readCount = 0;
copy data to buffer until newline
clear the keyboard buffer until newline
match the pattern and write to the vargs
for every pattern matched, readCount ++
return readCount;
Since every scanf will try to parse and clear the keyboard buffer until newline. so you cannot type 2 chars in the same line.
You can 2 easy solution for this.
1) scanf( "%c%c", &a, &b )
which is not general purpose
2) std::cin >> a >> b;
which is general purpose, but from my experience, this method is a bit slower than scanf.

Related

How does C++ buffer work(about whitespace)?

Assume that i put ' 123abc' as input in C++ console application.
if i get input as
int a; char ch;
scanf("%d", &a);
scanf("%ch", &ch);
i got 123 in a, 'a' in ch. Right?
Then, where does 4 blanks go? scanf just blow away blanks?
Is there no way can i get that blanks after i get 123abc?
To sum it up my question,
When i get int input with scanf, does scanf blow away blank in buffer?
What does happen i execute that code?
Can i get 4 blanks in ' 123abc' after i get '123' and 'a'?
As others pointed out, you really should read scanf documentation so you can see which specifier will be able to read whitespaces.
Regarding your first question:
When i get int input with scanf, does scanf blow away blank in buffer? What does happen i execute that code?
For numeric inputs, scanf will ignore any whitespace character.
When you execute scanf("%d", &a); it will go over the spaces (or any other whitespace character) until it finds a digit and start reading a decimal integer (as specified by %d).
Regarding your second question:
Can i get 4 blanks in ' 123abc' after i get '123' and 'a'?
I'm not sure what you mean here, you want to read a past value after having gone through the whole buffer?
You won't be able to do this.
If you need the spaces, get them before reading anything else.
Or read the whole buffer into your own buffer and deal with it.
There are many ways to deal with this.
Here's an example:
#include <cstdio>
int main()
{
{
printf( "Reading into your own buffer:\n" );
char my_buffer[128];
scanf( "%127[^\n]%*c", my_buffer ); // the %*c is to throw away the trailing \n
printf( "my_buffer: [%s]\n", my_buffer );
}
{
printf( "Reading each part separately:\n" );
char spaces[5];
int number;
char remaining_chars[4];
scanf( "%4[ ]", spaces );
scanf( "%d", &number );
scanf( "%3s", remaining_chars );
printf( " spaces: [%s]\n", spaces );
printf( " number: [%d]\n", number );
printf( "remaining_chars: [%s]\n", remaining_chars );
}
return 0;
}
And here is a sample run:
Reading into your own buffer:
123abc
my_buffer: [ 123abc]
Reading each part separately:
123abc
spaces: [ ]
number: [123]
remaining_chars: [abc]
I recommend you to read this documentation about scanf.
Whitespace character: the function will read and ignore any whitespace
characters encountered before the next non-whitespace character
(whitespace characters include spaces, newline and tab characters --
see isspace). A single whitespace in the format string validates any
quantity of whitespace characters extracted from the stream (including
none).
and if you wont to read sentence you can use fscanf or getline
EDIT This is how to do it -
scanf(" %[^\n]",str);
the anser is from this qustion here

how scanf handles standard input vs pipelined input

In the following code:
#include <cstdio>
using namespace std;
int N;
char x[110];
int main() {
scanf("%d\n", &N);
while (N--) {
scanf("0.%[0-9]...\n", x);
printf("the digits are 0.%s\n", x);
}
}
when I enter the input through file using command
./a.out < "INPUTFILE"
It works as expected but when I enter the input through std input it delay the printf function.
Why is that?
Input
3
0.1227...
0.517611738...
0.7341231223444344389923899277...
Output through file
the digits are 0.1227
the digits are 0.517611738
the digits are 0.7341231223444344389923899277
output through standard input
the digits are 0.1227
the digits are 0.517611738
The code is from a book, commpetitive programing 3 ch1_02_scanf.cpp.
Because there's an extra \n in your scanf format string, it will read and discard ALL whitespaces (spaces, newlines and tabs, if present). There needs to be an indication of the end of a whitespace sequence, so you should either hit Ctrl-D for EOF, or enter another non-WS character that lets scanf stop.
As Sid S suggests, you cam alternatively change your format string like this:
scanf(" 0.%[0-9]...", x);
The program works because when you redirect its stdin to a file, scanf will know if it reaches EOF and terminates the last input. You need to manually give an EOF when you type from console. That's the difference.
Change the second scanf() line to
scanf(" 0.%[0-9]...", x);

Difference between cin and cin.get() for char array

I have these 2 codes:
char a[256];
cin>>a;
cout<<a;
and
char a[256];
cin.get(a,256);cin.get();
cout<<a;
and maybe, relative to the second one without cin.get();
char a[256];
cin.get(a,256);
cout<<a;
My question is (first one) : for a char array, what should i use? cin or cin.get()? And why should i use cin.get(); with no parameter after my char initialisation?
And my second question is: my c++ teacher taught me to use every time cin.get() for initialisation chars and AFTER every initialisation char array or int array or just int or whatever, to again put cin.get(); after it. That's what i wanted to ask initially.
So, now i got these 2:
In this case, without cin.get() after the integer initialisation, my program will break and i can't do anymore my char initialisation.
int n;
cin>>n;
char a[256];
cin.get(a,256); cin.get(); // with or without cin.get();?
cout<<a;
And the correct one:
int n;
cin>>n; cin.get();
char a[256];
cin.get(a,256); cin.get(); // again, with or without?
cout<<a;
So, what's the matter? Please someone explain for every case ! Thank you.
They do different things, so choose whichever does what you want, or the better alternatives given below.
The first cin>>a; reads a single word, skipping over any leading space characters, and stopping when it encounters a space character (which includes the end of the line).
The second cin.get(a,256);cin.get(); reads a whole line, then consumes the end-of-line character so that repeating this will read the next line. cin.getline(a,256) is a slightly neater way to do this.
The third cin.get(a,256) reads a whole line but leaves the end-of-line character in the stream, so that repeating this will give no more input.
In each case, you'll get some kind of ill behaviour if the input word/line is longer than the fixed-size buffer. For that reason, you should usually use a friendlier string type:
std::string a;
std::cin >> a; // single word
std::getline(std::cin, a); // whole line
The string will grow to accommodate any amount of input.
The problem, most likely, is in the way you enter the values later on. The cin.get() after every initialization is there to "grab" the newline character that gets put in the stream every time you press enter.
Say you start entering your values like this:
2
a b c d...
Assuming you have pressed enter after 2, the newline character was also put on the stream. When you call cin.get() after that, it will grab and discard the newline character, allowing the rest of your code to properly get the input.
To answer your first question, for an array, you should use cin.get instead of the overloaded operator >> cin>> as that would only grab a single word, and it would not limit the amount of characters grabbed, which could lead to an overflow and data corruptions / program crashing.
On the other hand, cin.get() allows you to specify the maximum number of characters read, preventing such bugs.
For a char array use cin.get() because it counts whitespace whereas cin does not. More importantly, cin.get() sets the maximum number of characters to read. For example:
char foo[25]; //set maximum number of characters
cout << "Please type in characters for foo" << endl;
cin.get(foo,25);
cout << ' ' << foo;
In this case, you can only type in 24 characters and a null terminator character \0.
I hope this answers your first question.
I would personally use a string.

skip a specific set of characters scanf is not defined?

I was reading the documentation of scanf function in this page http://en.cppreference.com/w/cpp/io/c/fscanf and I thought I understood it well until I try this
int main(){
char p[100],t[100];
scanf("%s : %s", p, t);
printf("%s %s", p, t);
}
for my input I used test : scanf for me, the result should be test : but I get test scanf where the scanf function skip the : I don't understand why, I think that nowhere explain, can someone explain me?
thanks
From cplusplus.com,
scanf reads data from stdin and stores them according to the parameter format which can only contain a white space character,a non-white space character and format specifier.
Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace
character (whitespace characters include tab, space and newline).
Non-whitespace character, except format specifier (%): Any character that is not either a whitespace character (blank, newline or tab) or part of a format specifier (which begin with a %
character) causes the function to read the next character from the
stream.
Format specifiers: A sequence formed by an initial percentage sign (%) indicates a format specifier, which is used to specify the
type and format of the data to be retrieved from the stream and stored
into the locations pointed by the additional arguments.
So when you claim,
for my input I used test : scanf for me, the result should be
test : but I get test scanf where the scanf function skip the :
you are interpreting it wrong. scanf should skip the :(colon) or any character that you mention as its parameter. So when you provide an input like test CharachtersToSkip me with following code,
int main()
{
char p[100],t[100];
scanf("%s CharachtersToSkip %s", p, t);
printf("%s %s", p, t);
}
scanf will skip the characters and output only test me
Hope its clear.
if wants the out put "s=>test" only, then why you are print "t=>scanf"
just modify the code like that.
int main()
{
char p[100],t[100];
scanf("%s : %s", p, t);
printf("%s", p);
}
From the man page of scanf()
Matches a sequence of non-white-space characters;
The input string stops at white space or at the maximum field
width, whichever occurs first.
In this case, first %s will get the input until the white space character is occur. So your input is test : scanf. It will get the test for first input. Then it will skip the leading spaces, you are mentioning the : in scanf, so it will skip the colon :. Then get the next string.
For more example , try this code
int main()
{
int a;
scanf("%d ",&a);
printf("a:%d",a);
return 0;
}
In this code, scanf() don't end when you are giving the '\n' after the input.
It will wait for other than white space character occurs.

scanf - program waits for another like?

In the following program, I expect that after entering a word and hitting the enter key I should immediately see the message printfed out. However, it doesn't happen until I enter some other random word. Why is that?
#include <cstdio>
#include <cstdlib>
using namespace std;
char tictac[17];
int main()
{
scanf("%s\n", tictac);
printf("%s\n", tictac);
return 0;
}
tl;dr: with scanf("%s\n", tictac); you are asking to read a string, ignore all blank characters after it and then a read a new line. The problem is since all blanks are ignored by the first one there should be a at least one non blank character between the first Enter and the second Enter (hence the need for some garbage non-blank input before the second Enter is accepted.).
Here is an example usage of \n with scanf.
char x, y;
scanf("%c", &x);
scanf("%c", &y);
printf("%c %c", x,y);
with this code you will see that entering one character and pressing Enter will directly go to the printf statement. This is because the second scanf reads the carriage return (which itself is a character) in to y.
scanf("\n%c", &y); // This is recommended to do if you have a sequence of scanfs (but not on the first one).
With this one the stray carriage return will be ignored (or matched) with \n. And the correct character will be read to y.
Now when we come to your code
scanf("%s\n", tictac);
%s tells scanf to read until it finds a blank character (space, tab or new line) and then here is the catch ignore all blank spaces till a non blank space character is met. So your scanf will ignore the Enter you pressed when you entered the string. And any blank character that follows it (try entering spaces on the second line and press enter.)
Which means this will work just fine (unlike the char version)
scanf("%s", tictac);
scanf("%s", tictac2);
Actually on Windows
Because "%s" causes the library to read the input string until it
finds some white space, the equivalent format specifier is
"%[^\0x20\t\n]", which instructs the library to read the string until
it encounters a space character (\0x20), a tab character (\t), or a
newline character (\n).
However since you have explicitly asked scanf to match \n
scanf("%s\n", tictac);
^^
it will wait until it gets another \n (after a non blank character) because the first one one was used by %s.
Drop the \n from your scanf call.
There's a good explanation of scanf here. In your case, you should remove the \n from your scanf function.