skip a specific set of characters scanf is not defined? - c++

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.

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

scanf() doesn't accept whitespace

I need a scanf() call to accept whitespace (no tabs or newlines, just ' ' space glyphs).
char buffer[2048];
scanf(" %2048[0-9a-zA-Z ]s", buffer);
This format specifier I got from the answer to this question:
how-do-you-allow-spaces-to-be-entered-using-scanf
While it accepts the first sequence of input just fine, it terminates where the first whitespace character is, with a null character. What's going on? Am I perhaps using the wrong format?
I should say, I'm using scanf() here because safety isn't a concern; I'm the only person who'll ever use this particular program, and the input is rigidly formatted.
Use scanf("%[^\n]",buffer);. It will accept white space.
Sample program-
int main()
{
char buffer[2048];
printf("Enter the string\n");
scanf("%[^\n]",buffer);
printf("%s\n", buffer);
return 0;
}
output-
root#sathish1:~/My Docs/Programs# ./a.out
Enter the string
abc def ghi ijk
abc def ghi ijk
root#sathish1:~/My Docs/Programs#
Scanf isn't good for dealing with format that you're expecting to have a particular amount of whitespace. From the scanf man page:
White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input.
And:
[
Matches a nonempty sequence of characters from the specified set of
accepted characters; the next pointer must be a pointer to char, and
there must be enough room for all the characters in the string, plus a
terminating NUL character. The usual skip of leading white space is suppressed.
This means you can do something like
scanf("%[^\n]",buffer);
which says: "Read everything but the newline at the end of the string".
Or, if you're wanting to skip the first space, you can do:
scanf("%*[ ]%[^\n]",buffer);
This says "Read but ignore a space character, then read everything else into buffer".
While you can use scanf, if you are reading lines of text, getline is preferred and provides the advantage of dynamic memory allocation (when line = NULL). getline does read/save the newline character, so if that isn't desired, it can be easily stripped. The following example illustrates the point:
#include <stdio.h>
int main (void) {
char *line = NULL;
ssize_t read = 0;
size_t n = 0;
printf ("\nEnter a line of text: ");
read = getline (&line, &n, stdin);
line [read - 1] = 0; /* strip newline from string (optional) */
read--;
printf ("\n read '%zd' characters: '%s'\n\n", read, line);
return 0;
}
output:
./bin/getln
Enter a line of text: this is a line of text with white .. .. space.
read '52' characters: 'this is a line of text with white .. .. space.'
fgets(string, sizeof(string), stdin) will accept or scanf("%[\n]s",string); will accept

What's wrong with my program (scanf, C++)?

What wrong with this program?
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
using namespace std;
int N;
char x[110];
int main() {
scanf("%d", &N);
while (N--) {
scanf("0.%[0-9]...", &x);
printf("the digits are 0.%s\n", x);
}
return 0;
}
this is a console application in VS 2013, here is a sample input and output:
input :
1
0.123456789...
output
the digits are 0.123456789
but when I input this to this the output I get : The digits are 0
I have tried inputitng and manually and by text, in Code::Blocks and VS 2013, but neither worked. And when inputting manually, the program doesn't wait for me to input the numbers after I have entered N.
What should I do?
The scanf() in the loop fails, but you didn't notice. It fails because it can't handle a newline before the literal 0. So, fix the format string by adding a space, and the code by testing the return value from scanf():
if (scanf(" 0.%[0-9]...", x) != 1)
…oops — wrong format…
The blank in the format string skips zero or more white space characters; newlines (and tabs and spaces, etc) are white space characters.
You also don't want the & in front of x. Strictly, it causes a type violation: %[0-9] expects a char * but you pass a char (*)[100] which is quite a different type. However, it happens to be the same address, so you get away with it, but correct code shouldn't do that.
Replace
scanf("0.%[0-9]...", &x);
with
scanf(" 0.%[0-9]...", x);
You need to provide the starting location of the array which is x, not &x. Also, the space at the beginning will read all the whitespace characters and ignore it. So the \n left by scanf("%d", &N); is ignored.

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.