C - getchar()没有正确读取输入的第二个字符

时间:2016-08-21 14:45:30

标签: 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("%d ", ch);
    digits[i] = ch - '0';
    printf("%d\n", ch);
    i++;
}

例如,当我输入1100时,我得到:

  

49 49

     

49 1

     

48 48

     

48 48

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

  

1 10 0 0

当我输入66666时,我得到:

  <54> 54 54

     

54 6

     <54> 54 54

     <54> 54 54

     

54 5

阵列是:

6 10 6 6 6

我尝试了一堆不同长度的其他数字,每次第二个数字都发生同样奇怪的事情,而第二个数字只发生同样奇怪的事情。有谁知道为什么?非常感谢!

4 个答案:

答案 0 :(得分:10)

int digits[0];

你有一个数字保持零位数。

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

答案 1 :(得分:6)

正如已经指出过两次,你的数组的大小为零,因此无法容纳你试图推进的所有数字。

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

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

请注意,在数组范围之外进行写入和读取是未定义的行为,并且可能比这个更糟糕的副作用。试着在将来避免它。

答案 2 :(得分:4)

  

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

这是因为您已将数组digit声明为zero-size array,并且编译器不会为您的数组分配任何内存。因此,写入数组中的任何位置实际上将写入分配用于其他目的的存储器位置(如分配给其他变量),并且它将具有undefined behavior

所以,你得到的结果是由于UNDEFINED BEHAVIOR,在你的情况下,使用带有digit的索引写入任何位置实际上是写入分配给程序中其他变量的内存并且通过digit[1]获得的内存位置恰好是分配给程序中ch类型的变量char的内存位置。因此,写入内存位置digit[1]将修改您的ch变量。由于它是undefined behavior,因此您的计划可能会获得Segmentation Fault

要解决您的问题,请将数组digit声明为足够大。

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

但是,在标准C和C ++中,不允许zero-size array,如果您正在使用GCC,请使用-pedantic选项进行编译。它会发出警告,说:

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

对于C ++,它会发出类似的警告。

此外,零大小数组作为结构的最后一个元素非常有用,它实际上是一个可变长度对象的头。它们在GNU C中被允许。以zero-size array作为最后一个元素的结构称为variable-length structure。您可以阅读更多相关信息here

答案 3 :(得分:3)

发布的代码存在许多小问题:

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

  2. while()循环,即使digits[]被正确声明,也不会停止输入字符(只要不是EOF而不是换行符),所以可以超出任何数组大小

  3. 发布的代码不会关注EOF条件

  4. 这里有一些代码可以正常工作,最多只允许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++;
        }
    }
    

    这是一个示例输入

    1 2 3 4 5 6
    

    和结果输出

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

    注意:32 -16来自输入中的空格,因此为了获得最佳结果,应修改代码以忽略除数字输入之外的其他