c - 分配字符串的大小有什么意义?

标签 c

例如,如果我从 scanf 函数存储 ABCDE,后面的 printf 函数会给我 ABCDE 作为输出。那么分配字符串的大小有什么意义(这里是 4)。

#include <stdio.h>

int main() { 

    int c[4];

    printf("Enter your name:");
    scanf("%s",c);
    printf("Your Name is:%s",c);
    
    return 0;
}

最佳答案

首先,不要使用 int 数组来存储字符串!

int c[4] 分配一个包含 4 个整数的数组。 int 通常为 4 个字节,因此通常为 16 个字节(但在某些平台上可能为 8 或 32 或其他字节)。

然后,您首先使用此分配通过scanf 读取字符。如果你输入ABCDE,它用完了6个字符(字符串末尾有一个额外的0字节标记结束,这也需要空间),这恰好适合为数组保留的内存4 个整数。现在你可能真的很不走运并且拥有一个平台,其中 int 有一个所谓的“陷阱表示”,这会导致你的程序崩溃。但是,如果您不是在为一些非常奇特的设备编写代码,那么就不会。现在碰巧,这段代码可以工作了,原因与 memcpy 可以工作的原因相同:char 类型在 C 中是特殊的,并且允许将字节复制到并且来自不同的类型。

当您使用 %s 格式使用 printf 打印 int[4] 数组时,会发生相同的特殊处理。它有效,因为 char 很特殊。

这也证明了 scanfprintf 是多么不安全。他们很乐意接受你给他们的 c,并假设它是一个具有有效大小和数据的字符数组。

但是,不要这样做。如果要存储字符串,请使用 char 数组。正确的代码是:

#include <stdio.h>

int main() { 

    char c[16]; // fits 15 characters plus terminating 0

    printf("Enter your name:");
    int items = scanf("%15s",c); // note: added maximum characters
    // scanf returns number of items read successfully, *always* check that!
    if (items != 1) {
        return 1; // exit with error, maybe add printing error message
    }
    printf("Your Name is: %s\n",c); // note added newline, just as an example
    return 0;
}

关于c - 分配字符串的大小有什么意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69461186/

相关文章:

c - 使用命名管道 C 读写

c - Kaa ESP8266编译器错误

C 程序两个日期之间的天数——输出稍微太高?

c++ - 每次需要时将整个文件从磁盘复制到内存以处理或读取文件中的数据,直到文件全部读取

c - Redis 源代码(简单动态字符串)中的一个 if-else block ,我无法理解

c - "Invisible"操作二维数组时出错。 (0 个错误,0 个警告)

c - fork() 返回值错误

将C程序转换为汇编代码

比较目标文件以查找变量更改

c - C 中段错误的不稳定行为