Reputation: 1250
I am attempting to format a space-delimited user input for a programming assignment.
Essentially, the input consists of an arbitrary number of expressions
L integer integer integer integer
and C integer integer integer
.
For example: L 1 1 5 7 C 4 5 3
.
So far, I've managed to extract the integers depending on the initial character, and can iterate through the string using the scanf function:
char a;
while(scanf("%c", &a) == 1){
if(a == 'C'){
int inputX, inputY, inputR;
scanf("%d %d %d", &inputX, &inputY, &inputR);
printf("%d %d %d\n", inputX, inputY, inputR);
}
else if(a == 'L'){
int x1, y1, x2, y2;
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
printf("%d %d %d %d\n", x1, y1, x2, y2);
}
}
Unfortunately, although this outputs the desired integers, the loop (and user input prompt) doesn't terminate.
Could someone please enlighten me as to why this is happening?
Upvotes: 8
Views: 106569
Reputation: 109
char a;
while(scanf("%[LC]", &a) == 1){
if(a == 'C'){
int inputX, inputY, inputR;
scanf("%d %d %d%*c", &inputX, &inputY, &inputR);
printf("%d %d %d\n", inputX, inputY, inputR);
}
else if(a == 'L'){
int x1, y1, x2, y2;
scanf("%d %d %d %d%*c", &x1, &y1, &x2, &y2);
printf("%d %d %d %d\n", x1, y1, x2, y2);
}
}
"%[LC]" makes sure that only 'L' or 'C' will be scanned. After taking 3 or 4 of an integer input accordingly, both 'space' or 'enter' or 'any single character' will be discarded "%*c", after that, anything but 'L' or 'C' will break loop.
Upvotes: 0
Reputation: 105992
This is because \n
is always there to make scanf("%c", &a) == 1
always true.
Change your
while(scanf("%c", &a) == 1)
to
while(scanf(" %c", &a) == 1)
// ^space before format specifier.
A space before %c
will eat up this \n
left behind by scanf
(on pressing Enter).
Upvotes: 21
Reputation: 153338
Combining some features of other posts and some additions.
Use fgets()
and %n
inside sscanf()
. Be sure to check results of sscanf()
.
char line[1024];
while (fgets(line, sizeof line, stdin) != NULL)) {
char *s = line;
char Type;
int n;
while(sscanf(s, " %c%n", &Type, &n) == 1) {
s += n;
if(Type == 'C') {
int inputX, inputY, inputR;
if (3 != sscanf(s, "%d %d %d%n", &inputX, &inputY, &inputR, &n)) {
Handle_Syntax_Error();
}
s += n;
printf("%d %d %d\n", inputX, inputY, inputR);
}
else if(Type == 'L') {
int x1, y1, x2, y2;
if (4 != sscanf(s, "%d %d %d %d%n", &x1, &y1, &x2, &y2, &n)) {
Handle_Syntax_Error();
}
s += n;
printf("%d %d %d %d\n", x1, y1, x2, y2);
}
else {
Handle_Syntax_Error();
}
}
}
Upvotes: 1
Reputation: 495
The reason is scanf reads directly from the standard input and which blocks and waits for user input after it has processed the line. What you need to do is read the line and process that line in your while loop. I've modified your code below.
char a;
char line[1024];
fgets(line, 1023, stdin); // leave 1 character for null terminator
while(sscanf(line, "%c", &a) == 1){
if(a == 'C'){
int inputX, inputY, inputR;
sscanf(line, "%d %d %d", &inputX, &inputY, &inputR);
printf("%d %d %d\n", inputX, inputY, inputR);
}
else if(a == 'L'){
int x1, y1, x2, y2;
sscanf(line, "%d %d %d %d", &x1, &y1, &x2, &y2);
printf("%d %d %d %d\n", x1, y1, x2, y2);
}
}
Upvotes: 3