Reputation: 39
Im trying to parse an input string in the format x y z
(spaces included) so that it will exit the loop when the entered string is valid. However, when I run this code, it outputs "incorrect format" 3 times and each time, valid = 1
. Is there any other way to get this to work without having to parse it manually?
int valid = 0, x, y, z;
char str[20];
while (valid != 3) {
scanf("%s", str);
valid = sscanf(str, "%d %d %d", &x, &y, &z);
if (valid != 3) {
printf("Incorrect format\n");
}
}
Upvotes: 0
Views: 771
Reputation: 84579
In your code, the primary stumbling block you create is to attempt a read with scanf ("%s", str)
. The %s
format specifier will only read characters up to the first whitespace encountered. If you enter 3-integers separated by a space, you will never read more than the first one into str
. This makes it impossible to parse 3-integer values with sscanf
from str
that can contain no more than 1.
To correct the problem, either read 3-integer values directly with scanf
, e.g.
#include <stdio.h>
int main (void) {
int x, y, z;
printf ("enter 3 integers: ");
if (scanf ("%d %d %d", &x, &y, &z) != 3) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
printf ("x : %d\ny : %d\nz : %d\n", x, y, z);
return 0;
}
Or, the preferred way to handle line-oriented input is by using the line-oriented input functions fgets
or POSIX getline
. This will avoid the many pitfalls with taking user input with scanf
that new C programmers routinely fall into. Never, never, never use gets
, it is so insecure it has been removed from the C11 library.
An equivalent example using fgets
and sscanf
would be:
#include <stdio.h>
#define MAXC 128
int main (void) {
int x, y, z;
char buf[MAXC] = "";
printf ("enter 3 integers (on a single line): ");
if (fgets (buf, MAXC, stdin) == NULL) {
fprintf (stderr, "error: user canceled input.\n");
return 1;
}
if (sscanf (buf, "%d %d %d", &x, &y, &z) != 3) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
printf ("x : %d\ny : %d\nz : %d\n", x, y, z);
return 0;
}
Example Use/Output
(it is the same for both)
$ ./bin/rd3int
enter 3 integers: 10 12 14
x : 10
y : 12
z : 14
Look things over and let me know if you have further questions.
Upvotes: 4
Reputation: 3818
scanf("%s", str)
scans text until space occurs. So for input 1 2 3
, str
is read 3 times, with content 1
, 2
, 3
.
Try using gets(str)
instead.
Upvotes: 0