xyz
xyz

Reputation: 413

Why scanf cannot read my input?

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");
    }   
}

enter image description here

However, when I input the first line Q 1 3, this program end. I don't know why?

Upvotes: 3

Views: 1774

Answers (3)

user6710094
user6710094

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

Some programmer dude
Some programmer dude

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Related Questions