How to take character input if we have multiple white spaces? - c

Hello Everyone,
I am solving a question http://www.spoj.com/problems/ARITH2/. In this question I have to take first integer input then a character input, but there is no limitations of white spaces. how do I take only character input then integer input?

Use any whitespace character before %c. This character will discard all whitespace characters ,if any, until the first non-whitespace character. For example:
scanf(" %c", &character);
Note that you do not need this before %d as %d already discards leading whitespace characters.
As for the link to the challenge provided in the question, you can use
scanf("%d", &no_of_test_cases);
to get the number of test cases and
scanf("%d %c", &number, &character);
to get each number and character. Use the above scanf in a loop until character becomes '='. You'll get each line for each test case by doing this.

Related

Why can't I use "%[^\n]" scanset?

I'm trying to get user input for my string with spaces on my program but for some reason %[^\n] doesn't work.
The % part is marked red. I couldn't understand why. It just skips and doesn't ask for user input.
int prelim, midterm, semiFinal, final, totalScore, yearLevel, studentId;
float averageScore = 0;
char name[25], degree[25];
printf("Enter your student id: ");
scanf("%d", &studentId);
printf("Name: ");
scanf("%[^\n]s", &name);
printf("Degree: ");
scanf("%[^\n]s", &degree);
printf("Year: ");
scanf("%d", &yearLevel);
First of all, scanf("%[^\n]s", &name) must be scanf("%[^\n]", name) as
The s is not part of the %[ format specifier as people new to C often think.
The ampersand should be removed as the name of an array decays to a pointer to its first element which is already the type that %[ expects.
Now, to answer your question, %[^\n] will fail if the first character it sees is a \n. For the scanf for studentId, you type the number and press Enter. That scanf consumes the number but leaves the enter character (\n) in the input stream. Then, the scanf for name sees the newline character and since it's the first character that it sees, it fails without touching name. The next scanf fails for the same reason and the last scanf waits for a number.
But wait! Why doesn't the last scanf fail as well? The answer to that is certain format specifiers like %d skip leading whitespace characters. The %[ format specifier does not.
Now how do we fix this? One easy solution would be to tell scanf to skip whitespace characters before the %[ format specifier. You can do this by adding a space before it: scanf(" %[^\n]", name). When scanf sees the space, it will skip all whitespace characters from the input stream until the first non-whitespace character. This should solve your problem.

Scanf reads wrong value

I’m new to C programming language, I have wrote a simple code that reads two “char” values and prints them on the screen but the second one got empty value for a strange reason. What’s going wrong with my code?
Char c;
Scanf(“%c”,&c);
Printf(“Value:%c”,c);
Scanf(“%c”,&c);
Printf(“Value:%c”,c);
Output:
Value:g
Value:
(This is a comment, but comments are hard to format)
There's nothing wrong with your code (other than the failure to check the value returned by scanf and deal with errors or incorrect input). Consider:
#include <stdio.h>
int
main(void)
{
char c;
scanf("%c",&c);
printf("Value:%c",c);
scanf("%c",&c);
printf("Value:%c",c);
return 0;
}
$ gcc a.c
$ printf 'abc' | ./a.out
Value:aValue:b
Perhaps what's "wrong" is that you have newlines in your input. (eg, you are entering data interactively and forgetting that when you hit "return" a newline is inserted into the input stream.)
If your goal was to read two "interesting" characters, and if you don't think that whitespace characters like space and newline are "interesting", you've been tripped up by number six out of the seventeen things about scanf that are designed to trip up the unwary: %c does read whitespace characters.
If you want scanf to skip over whitespace characters, so that %c will read the next, non-whitespace or "interesting" character, simply include a space character in the format string before the %c:
char c;
scanf(" %c", &c);
printf("Value: %c\n",c);
scanf(" %c", &c);
printf("Value: %c\n",c);
In a scanf format string, the presence of a whitespace character indicates that you want scanf to skip over all whitespace at that point in the input.
Normally you don't have to worry about skipping whitespace with scanf, because most of the other format specifiers -- %d, %f, %s, etc. -- automatically skip over any whitespace, if necessary, before they start parsing their input. But %c is special: someone thought you might want to use it to read whitespace characters, so it doesn't skip them, so if you don't want to read them, you have to skip them yourself, with that space character in the format string first.

What is the effect of space at different places in the scanf format string?

The below is what I understood so far. Please confirm, add, correct as the case may be -
scanf (" %c %d %s", &a, &b, c);
In the above - the first space before %c makes sure the buffer is cleared before scanf starts accepting new string into it from stdin for this particular function scanf call. This clears any of the delimiters from any previous input function calls..
The remaining two spaces before %d and %s allow any number of spaces or tabs but not enter key press between the user's entry of a, b and b,c , respectively.
Even with the above, none of the inputs can contain a space in it i.e. space is the delimiter for each of the three inputs. To add space it has to be specified in the string control braces [] like "%[a-z A-Z_0-9]" can contain any upper or lower case alphabets, digits 0-9, a space and an underscore - but will treat all other characters as invalid - The invalid character will go to the next input in the format string, if any, so if %[___] above was followed by %c and an astrick is pressed, the astrick is put into the character corresponding to %c.
Please confirm, correct, add. Thanks.
From cppreference.com:
Any single whitespace character in the format string consumes all available consecutive whitespace characters from the input
So all the spaces in the format string just mean to skip over any whitespace in the input.
There's no difference between the spaces before %c and the other spaces. The initial spaces don't clear the buffer, it just skips over any initial whitespace in the input. This ensures that %c will read the first non-whitespace character in the input.
Whitespace includes space, TAB, and newline characters. So you can put spaces or press enter between each input.
You don't actually need the spaces before %d or %s. These formats don't read anything that contains whitespace, and they automatically skip over any whitespace before the object they read. The spaces in the format string are redundant and do no harm, and may make it easier to read.
All conversion specifiers other than [, c, and n consume and discard all leading whitespace characters (determined as if by calling isspace) before attempting to parse the input.
...
The conversion specifiers that do not consume leading whitespace, such as %c, can be made to do so by using a whitespace character in the format string
the first space before %c makes sure the buffer is cleared before scanf starts accepting new string into it from stdin for this particular function scanf call. This clears any of the delimiters from any previous input function calls.
No. The buffer is not cleared and there are no delimiters.
The remaining two spaces before %d and %s allow any number of spaces or tabs but not enter key press between the user's entry of a, b and b,c , respectively.
No. The enter key produces a newline character, which is whitespace.
Even with the above, none of the inputs can contain a space in it i.e. space is the delimiter for each of the three inputs.
No.
The invalid character will go to the next input in the format string
Yes. This isn't limited to %[ ]: If e.g. %d sees 12foo in the input stream, it will consume 12 and leave foo to be read by the rest of the format string (however, if there are no leading digits at all, %d will fail and abort processing).
Any whitespace character in the format string reads and consumes all available whitespace characters at this point in the input stream, including spaces, tabs, and newlines. It doesn't matter whether the space appears before %c or %d or %s: All whitespace (including newlines) in the input is skipped.
%c accepts spaces just fine. Space is not a delimiter because %c has no delimiters; it always reads a single character. The only reason it can't read a space in your code is that it is preceded by in the format string, which will have skipped over all available whitespace.
As for %d and %s, they implicitly skip leading whitespace. That is, " %d" is equivalent to "%d" and " %s" is equivalent to "%s".

Using scanf in for loop

Here is my c code:
int main()
{
int a;
for (int i = 0; i < 3; i++)
scanf("%d ", &a);
return 0;
}
When I input things like 1 2 3, it will ask me to input more, and I need to input something not ' '.
However, when I change it to (or other thing not ' ')
scanf("%d !", &a);
and input 1 ! 2! 3!, it will not ask more input.
The final space in scanf("%d ", &a); instructs scanf to consume all white space following the number. It will keep reading from stdin until you type something that is not white space. Simplify the format this way:
scanf("%d", &a);
scanf will still ignore white space before the numbers.
Conversely, the format "%d !" consumes any white space following the number and a single !. It stops scanning when it gets this character, or another non space character which it leaves in the input stream. You cannot tell from the return value whether it matched the ! or not.
scanf is very clunky, it is very difficult to use it correctly. It is often better to read a line of input with fgets() and parse that with sscanf() or even simpler functions such as strtol(), strspn() or strcspn().
scanf("%d", &a);
This should do the job.
Basically, scanf() consumes stdin input as much as its pattern matches. If you pass "%d" as the pattern, it will stop reading input after a integer is found. However, if you feed it with "%dx" for example, it matches with all integers followed by a character 'x'.
More Details:
Your pattern string could have the following characters:
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).
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,
compare it to this non-whitespace character and if it matches, it is
discarded and the function continues with the next character of
format. If the character does not match, the function fails, returning
and leaving subsequent characters of the stream unread.
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.
Source: http://www.cplusplus.com/reference/cstdio/scanf/

why to put space between %d and %c while inputting there values using scanf

im a beginner to C,, and i was writing a code to print a square of a user entered character.
usually when we need to input two integers (say x and y) using scanf() we write this scanf("%d%d", &x, &y) but according to the needs of my code i am supposed to input one integer (say m) and a character (say ch).
I wrote it as scanf("%d%c", &x, &ch) but it has an error, when i execute the program it only asks the integral value to be entered and then it just stop executing.
I searched for this and i found that i need to put space between %d and %c as scanf("%d %c", &x, &ch);
Can anyone explain this why we need to put space between this?
Meaning of whitespace characters in the format string (from http://www.cplusplus.com/reference/cstdio/scanf/?kw=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).
When your code is:
scanf("%d%c", &x, &ch)
and you enter
10
in your console:
10 is read and stored in x.
the newline character is read and stored in ch.
If you use
scanf("%d %c", &x, &ch)
and you enter
10
10 is read and stored in x.
the newline character and other whitespace characters are consumed. The program waits for a non-whitespace character. Once a line of input is entered and at least one non-whitespace character is present in the line, the first non-white character of the line is read into ch. This is because stdin is typically line buffered.
Almost all format specifiers in scanf automatically skip all whitespace before trying to read anything. That's, for example, how %d works (as well as %s, %f and most other specifiers). However, %c is an exception from this behavior. %c does not skip whitespace. If your input data contains a whitespace character, %c will happily read that character into your ch variable.
This is most likely what happens in your case. If you enter
5 #
to create a 5x5 square of #s, the %d specifier will read 5 into x and stop reading at the space character. Then %c will read that space character into ch. And then your program will just proceed, leaving the # unread. It is quite possible that the rest of your program actually works as intended. It's just that since ch is a space character, it displays a 5x5 square of space characters, which are invisible :) To make your scanf in its original form work as intended you have to input your data as
5#
But a much better way to make sure that your scanf actually reads the # character into ch is to explicitly ask scanf to skip all whitespace before reading ch. In scanf this is done by inserting any whitespace character (space, newline, tab etc.) into the format string. This
scanf("%d %c", &x, &ch);
will force scanf to skip that space after 5 and read the # into ch. This will also work for inputs like this
5 #
and even like this
5
#
because scanf will automatically skip all whitespace until it hits the #. Note also that even with the updated format sting whitespace in the input is not required, meaning that this input
5#
will still work with the updated scanf.
You can also use these variants
scanf("%d\t%c", &x, &ch);
scanf("%d\n%c", &x, &ch);
scanf("%d %c", &x, &ch);
scanf("%d \n \t %c", &x, &ch);
to achieve the same thing. They are all equivalent. The first variant (with a space) just looks better.

Resources