2016-08-22 39 views
3

我想使用scanf()为下表阅读:为什么scanf无法读取我的输入?

Q 1 3 
U 2 6 
Q 2 5 
U 4 8 

这是我的代码:

#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

然而,当我输入的第一行Q 1 3,该程序结束。我不知道为什么?

+1

申报'A'如'char'指针和使用'的scanf( “%C”,一个+ 3 * I + J);'。 '%c'之前的空格是有意的。还要将'printf(“%d”,a [3 * i + j]);'改为'printf(“%c”,a [3 * i + j]);'。 (我假设在输入中只使用一个数字号码)。 – haccks

+0

请不要张贴动画GIF。如果您完全没有发布图片,最好将复制/粘贴到问题中并将其标记为代码。 – Barmar

回答

5

发生这种情况是因为您向想要读取%d的编号的程序提供了非数字输入。由于Q而不是一个数字,scanf失败。

但是,您的程序没有注意到scanf的返回值,并一直将其称为失败状态。该程序认为它正在获取一些数据,而事实上并不是。

为了解决这个问题,更改代码通过%c%s时,它读取非数字字符,检查scanf返回值,并摆脱无效的输入时scanf失败。

当您致电scanf时,它将返回与提供的%指定符相对应的多少个值。下面是如何检查的scanf返回值:

if (scanf("%d", a + 3 * i + j) == 1) { 
    ...     // The input is valid 
} else { 
    fscanf(f, "%*[^\n]"); // Ignore to end of line 
} 
1

这是因为字母Q不是数字,所以scanf将会失败,并保持输入缓冲区不变。因此,下一次迭代scanf将看到相同的Q并再次失败,依此类推...

这意味着实际上没有任何内容被读入您分配的内存中,并且您打印出未初始化的内存,导致到未定义的行为。为您解决问题

一种可能的方式可能是代替(例如使用fgets)读取线,然后用sscanf解析全线一气呵成。也许类似

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

我也建议你实际上初始化你分配的内存,特别是如果你不打算使用它的一部分,但仍把它打印出来。

+0

所以我想知道如何处理它? – xyz

+1

@ShutaoTang [scanf](http://linux.die.net/man/3/scanf)返回成功匹配的项目数量... – LPs

0

要么使用scanf()与int变量与适当的ASCII值或使用scanf()与char变量字符但在这两种情况%C打印。为Q ASCII码为81和用于Ü它是85.