Reputation: 413
I would like use scanf()
to read the following table:
Q 1 3
U 2 6
Q 2 5
U 4 8
This is my code:
#include <stdio.h>
#include <stdlib.h>
void main() {
int *a;
int i, j;
a = (int *) malloc(4 * 3 *sizeof(int));
printf("input:\n");
for (i = 0; i < 4; i++) {
for (j = 0; j < 3; j++) {
scanf("%d", a + 3 * i + j);
}
}
printf("output:\n");
for (i = 0; i < 4; i++) {
for (j = 0; j < 3; j++) {
printf("%d ", a[3*i+j]);
}
printf("\n");
}
}
However, when I input the first line Q 1 3
, this program end. I don't know why?
Upvotes: 3
Views: 1774
Reputation: 77
Either use scanf()
with int variable with proper ASCII value or use scanf()
with char variable for character but print with %c in both cases. ASCII code for Q is 81 and for U it is 85.
Upvotes: 0
Reputation: 409136
It's because the letter Q is not a number, so scanf
will fail and leave the input buffer untouched. So the next iteration scanf
will see the same Q and again fail, and so on and on and on...
That will mean nothing is actually read into the memory you allocate, and you print out the uninitialized memory, leading to undefined behavior.
One possible way to solve your problem might be to read lines instead (using e.g. fgets
), and then use sscanf
to parse the whole line in one go. Perhaps something like
for (i = 0; i < 4; i++) {
char buffer[64];
if (fgets(buffer, sizeof buffer, stdin) != NULL) {
char c; // The character
int a, b; // The integer values
sscanf(buffer, "%c %d %d", &c, &a, &b);
a[3 * i + 0] = c;
a[3 * i + 1] = a;
a[3 * i + 2] = b;
}
}
I also recommend you actually initialize the memory you allocate, especially if you're not going to use parts of it but still print it out.
Upvotes: 1
Reputation: 726479
This happens because you provided a non-numeric input to your program that wants to read a number with %d
. Since Q
is not a number, scanf
fails.
However, your program is not paying attention to the return value of scanf
, and keeps calling it in the failed state. The program thinks that it is getting some data, while in fact it does not.
To fix this, change the code to pass %c
or %s
when it reads the non-numeric character, check the return value of scanf
, and get rid of invalid input when scanf
fails.
When you call scanf
, it returns how many values corresponding to %
specifiers it has provided. Here is how to check the return value of scanf
:
if (scanf("%d", a + 3 * i + j) == 1) {
... // The input is valid
} else {
fscanf(f, "%*[^\n]"); // Ignore to end of line
}
Upvotes: 5