C变量"忘记"接受输入后它的价值是什么

时间:2017-03-10 06:03:35

标签: c arrays scanf

我写过我认为简单的代码,但是行为不端。

我的预期输出是:

I'm fine with printing it here 3 
Can be printed as much as I want 3
enter anything: d (I input anything here)
printing it again: 3 
I'm fine with printing it here 3 
...

哪个会无休止地循环,但这就是我收到的:

I'm fine with printing it here 3 
Can be printed as much as I want 3
enter anything: d
printing it again:
I'm fine with printing it here
...

基本上,在接受完全不相关的输入之后,它就好像忘记了num的值一样。这是我的代码:

#include <stdio.h>

int main() {
    char num[1] = "3";
    char entry;
    while(1) {
        printf("I'm fine with printing it here %s \n", num);
        printf("Can be printed as much as I want %s \n", num);
        printf("enter anything: ");
        scanf("%s", &entry);
        printf("printing it again:%s \n", num);
    }
}

此外,当我删除while循环时,输出变为乱码:

I'm fine with printing it here 3??U? 
Can be printed as much as I want 3??U? 
enter anything: d
printing it again: 

我是C的新手,我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

问题在于

 scanf("%s", &entry);

在哪里,你总是超越边界。这会调用undefined behavior

详细说明,entry可以容纳(只有一个)char,但是%s期望它的参数是指向char数组的指针,它存储所提供的数据输入,加上,空终止符。

现在即使对于单个字符输入,你也需要一个带有两个char元素的数组来存储它,包括终止空值,所以即使是最小的输入,你也要一个。< / p>

也就是说,您在使用num时遇到类似问题,在初始化时,您没有空终结符的空间。你应该写

char num[2] = "3"

或者,为了更好,将其留给编译器

char num[ ] = "3"

能够将num用作字符串

答案 1 :(得分:0)

调用任何scanf()系列函数时:

  1. 始终检查返回值(而不是参数值)以确保操作成功。
  2. 使用'%s'输入转换说明符时,始终包含MAX CHARACTERS修饰符,该修饰符比输入缓冲区的长度小1,以避免缓冲区溢出的未定义行为。
  3. 即。如果用户键入除“return / enter”键之外的任何内容,则char变量entry将始终超出。

    考虑到变量在内存中的布局方式,超越了数组entry上的num[]变量步骤

    这些行中的每一行也都有不确定的行为:

    printf("I'm fine with printing it here %s \n", num);
    printf("Can be printed as much as I want %s \n", num);
    printf("printing it again:%s \n", num);
    

    因为“%s”将保持打印内存,直到它发生在NUL('\ 0')字符上,数组num[]不包含NUL字节,因为它太短,结果在正在打印的数组num[]之外的内存中。