C-getchar()不';t无法正确读取输入的第二个字符

C-getchar()不';t无法正确读取输入的第二个字符,c,getchar,C,Getchar,我试图使用getchar()读取输入数字的所有数字并将它们存储在数组中。但每次我运行程序时,第二个数字都会出错 这是我的密码: int ch = 0; int digits[0]; int i = 0; while ((ch = getchar()) != '\n') { digits[i] = ch - '0'; i++; } 为了说明会出现什么问题,我插入了两个printf: while ((ch = getchar()) != '\n') { printf(&q

我试图使用
getchar()
读取输入数字的所有数字并将它们存储在数组中。但每次我运行程序时,第二个数字都会出错

这是我的密码:

int ch = 0;
int digits[0];
int i = 0;

while ((ch = getchar()) != '\n') {
    digits[i] = ch - '0';
    i++;
}
为了说明会出现什么问题,我插入了两个
printf

while ((ch = getchar()) != '\n') {
    printf("%d ", ch);
    digits[i] = ch - '0';
    printf("%d\n", ch);
    i++;
}
例如,当我输入
1100
时,我得到:

49 49

49 1

48 48

48 48

当我在一个单独的循环中打印数组时,输出是:

11000

当我输入
66666
时,我得到:

54 54

54 6

54 54

54 54

54 5

阵列是:

6 10 6 6 6
我试过很多其他长度不同的数字,每次第二个数字发生同样的奇怪事情,只有第二个。有人知道为什么吗?非常感谢

int digits[0];
您有一个包含零位的数组

int digits[32];     /* or some reasonable size, check for overflow... */

正如已经两次指出的,您的数组大小为零,因此无法容纳您尝试插入的所有数字

因此,当写入数组中的任何位置时,实际上是在写入用于其他内容的内存,例如按住
ch
。显然,恰好程序所期望的(不存在的)
数字[1]
所在的位置存储了
ch
。因此,您正在使用
ch-'0'
覆盖
ch

然后,当离开
ch
的范围时,程序可以自由地在那里编写其他内容。(因为显然不再需要内存了。)显然,它决定写一些有值的东西。这将导致“奇怪”的输出

请注意,在数组边界之外写入和读取是未定义的行为,可能会产生比此行为更糟糕的副作用。以后尽量避免

每次我运行程序时,第二个数字都会出错

这是因为您已将数组
数字
声明为
零大小数组
,编译器不会为数组分配任何内存。因此,写入数组中的任何位置实际上都会写入为其他目的分配的内存位置(如为其他变量分配的内存位置),并且它将具有
未定义的行为

因此,您得到的结果是由于
未定义的行为
,在您的情况下,使用带有
数字的索引写入任何位置实际上是写入分配给程序中其他变量的内存以及通过
数字[1]获得的内存位置
恰好是分配给程序中类型为
char
的变量
ch
的内存位置。因此,写入内存位置
数字[1]
将修改
ch
变量。由于它是
未定义的行为
,因此您的程序可能会出现
分段错误

要解决您的问题,请声明数组
数字
大小足够

#define SIZE_DIGITS  /* Sufficient Size required by your application */
int digit[SIZE_DIGITS];

不过,在标准C和C++中,不允许大小数组不允许,如果使用GCC,请用“代码> -PodiNoth< /Cord>选项编译它。它会发出警告,说:

zero.c:3:6: warning: ISO C forbids zero-size array 'a' [-pedantic]

在C++的情况下,给出类似的警告。


此外,零大小数组作为结构的最后一个元素非常有用,该结构实际上是可变长度对象的头。GNU C中允许它们。将
零大小数组作为最后一个元素的结构称为
可变长度结构
。您可以阅读更多信息。

发布的代码有一些小问题:

  • 数组
    digits[]
    设置为0大小,因此无法保存任何数字,因此尝试在
    digits[x]
    中放置任何内容会损坏堆栈

  • while()
    循环,即使正确声明了
    数字[]
    ,也不会停止输入字符(只要不是EOF和换行符),因此可能会超出任何数组大小

  • 发布的代码不监视EOF条件

  • 下面是一些可以正常工作的代码,最多只允许32位

    #include <stdio.h>
    
    #define MAX_DIGITS (32)
    
    int main( void )
    {
    
        int ch = 0;
        int digits[ MAX_DIGITS ];
    
    
        int i = 0;
        while ( i < MAX_DIGITS && ( (ch = getchar()) != EOF && '\n' !=  ch) ) 
        {
            printf("%d ", ch);
            digits[i] = ch - '0';
            printf("%d\n", digits[i]);
            i++;
        }
    }
    
    以及由此产生的输出

    49 1
    32 -16
    50 2
    32 -16
    51 3
    32 -16
    52 4
    32 -16
    53 5
    32 -16
    54 6
    

    注意:
    32-16
    来自输入中的空格,因此为了获得最佳结果,应修改代码以忽略除数字输入之外的其他数字[0]是否确实要一个大小为0的数组?需要考虑的问题:文件末尾会发生什么?这并不能回答问题。它只是告诉他们如何解决问题,而不是为什么会发生这种情况,以及实际问到了什么。@chux,我总是有可能看到我第一次写
    while()
    语句时额外检查了EOF条件。我将编辑我的答案以删除当前的#3个问题,您的答案也非常有用。非常感谢,您的答案非常详细。您确实回答了我的问题,谢谢。如果我能接受两个答案,那就是你的答案和我现在选择的答案:)
    49 1
    32 -16
    50 2
    32 -16
    51 3
    32 -16
    52 4
    32 -16
    53 5
    32 -16
    54 6