14

Consider the following code:

#include<stdio.h>
int main() {
    int i=3, j=4;
    scanf("%d c %d",&i,&j);
    printf("%d %d",i,j);
    return 0;
}

It works if I give 2c3 or 2 c 3 or 2c 3 as input if I have to change the value of variables. What should I do if I want the user to enter the same pattern as I want means if %dc%d then only 2c3 is acceptable and not 2 c 3 and vice versa if it is %d c %d?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Vaibhav Agarwal
  • 1,124
  • 4
  • 16
  • 25

4 Answers4

16

Whitespace in the format string matches 0 or more whitespace characters in the input.

So "%d c %d" expects number, then any amount of whitespace characters, then character c, then any amount of whitespace characters and another number at the end.

"%dc%d" expects number, c, number.


Also note, that if you use * in the format string, it suppresses assignment:
%*c = read 1 character, but don't assign it to any variable

So you can use "%d%*c c%*c %d" if you want to force user to enter: number, at least 1 character followed by any amount of whitespace characters, c, at least 1 character followed by any amount of whitespace characters again and number.

rubik
  • 8,814
  • 9
  • 58
  • 88
LihO
  • 41,190
  • 11
  • 99
  • 167
  • 2
    While correct, this doesn't actually answer the question as to how to proceed if you want to insist on whitespace or no whitespace. – Vicky Oct 11 '12 at 08:50
  • 2
    This answer incorrectly implies that whitespace is not allowed before the integer. `"%dc%d"` expects any amount of whitespace characters, number, `'c'`, any amount of whitespace characters, number.`. – chux - Reinstate Monica Jul 01 '16 at 20:45
8

If you want to accept 1c2 but not 1 c 2, use the pattern without the space:

scanf("%dc%d", &x, &y);

If you want to accept 1c2 and 1 c 2 (and also 1 \t \t c \t 2 etc), use the pattern with the space:

scanf("%d c %d", &x, &y);

If you want to accept 1 c 2 but not 1c2, add a fake string containing whitespace:

scanf("%d%*[ \t]c%*[ \t]%d", &x, &y);

Here the format string %[ \t] would mean "read a string that contains any number of space and tab characters"; but using the additional *, it becomes "expect a string that contains any number of space and tab characters; then discard it"

anatolyg
  • 26,506
  • 9
  • 60
  • 134
0

I think I would read the scanf result into different variables (i.e. not reuse i and j) as "%d%s%d". Then check the string you got from the %s and if it matches your requirements, use the other variables to overwrite i and j.

Vicky
  • 12,934
  • 4
  • 46
  • 54
0

Force a string parsing first :

char a[100], b[100];
scanf("%99s c %99s", a, b);

Then use sscanf() to convert the strings to int.

wldsvc
  • 1,242
  • 9
  • 13