【问题标题】:Why does scanf("%s") behave strangely with char*? [duplicate]为什么 scanf("%s") 对 char* 有奇怪的行为? [复制]
【发布时间】:2020-05-14 18:24:55
【问题描述】:

我试图解决this problem

当我创建 char * 并将其传递给 scanf 时:

char* input = "";
scanf("%s", input);

它的行为是weirdly
但是,当我更改定义并将 1000 个字符初始化为 \0:

char input[1000] = { '\0' };

它的行为正常。为什么会这样?

【问题讨论】:

标签: c string scanf


【解决方案1】:

我猜您看到的是分段错误。当您声明char* input = ""; 时,您将导致input 成为指向字符串文字的指针。字符串文字存储在内存的只读部分中。因此,尝试用scanf 覆盖数据是对内存的无效使用。

但是,当您声明char input[1000]; 时,您现在在堆栈上获得了一个数组,这是可以写入的内存部分。这就是代码有效的原因。

【讨论】:

    【解决方案2】:

    第一个问题是这声明了什么?

    char* input = "";
    

    这是非可变(只读)内存区域中的单个字节。如果你给它写任何东西,那就是未定义的行为,或者更通俗地说是奇怪的行为

    当您正确地重写它时,您会得到一个 1000 个字符的缓冲区,并且您可以读取它而不会出现未定义的行为,前提是您的输入是

    【讨论】:

    • 我可以让它动态改变字符串的大小吗?如果可以的话,值得吗?
    • 这不是(通常?)在只读内存中,因为它是一个字符串文字,所以写入它会导致问题?
    • @SamiKuhmonen 好点。一些编译器拒绝将其视为可变的,所以是的,它必须是const char* input = ""。我见过很多人根本不关心,或者至少不关心,除非用特定的编译器标志告诉它,并且让未定义的行为不受阻碍地溢出。
    • 这是完全错误的。那是一个字符串文字。无论大小如何,尝试通过指向字符串文字的指针写入都是未定义的行为。此外,不,它不一定是const“一些编译器拒绝将其视为可变” - 这是规定的标准,任何兼容的编译器都会拒绝将其视为可变的,因为它是 UB。
    • scanf("%1024s", &input) 如果input 缓冲区大小为1024 也是错误的,您应该改为scanf("%1023s", &input)
    猜你喜欢
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多