0

我正在学习c编程,我遇到了一些奇怪的事情。

我在搞乱 char 数组/字符串并使用不同的函数。所以我有这个程序,

#include <stdio.h>
int main(){
    char a[] = {'H','e','y','a','\0'};
    strcat(a,"bro!");
    printf(a);
}

$ gcc -o test.o test.c -Wall
$ ./test.o
Heya bro!
$

按预期工作,但如果我添加

#include <string.h>

从一开始,我就明白了

$ gcc -o test.o test.c -Wall
$ ./test.o
Abort: trap 6
$
4

2 回答 2

3

尝试附加字符,strcat但数组的大小再次不足以容纳它们给您未定义的行为。(在您的情况下,未定义的行为会导致您看到的错误 - 它可能是一切正常的情况。)因为strcat试图写超出数组a。的第一个参数printf应该是格式说明符,例如printf("%s",a);.

char a[] = {'H','e','y','a','\0'};

这里a有5个元素。数组的大小是5。你需要一个更大的数组。

char a[9] = {'H','e','y','a','\0'};

如果您让数组容纳 9 个字符,那么它会起作用。

于 2018-02-16T05:45:10.253 回答
3

当您初始化一个数组并省略维度时,编译器会根据初始化器的数量推断维度。
所以,这个声明:

char a[] = {'H','e','y','a','\0'};

相当于:

char a[5] = {'H','e','y','a','\0'};

strcat()源字符串的副本附加到目标字符串。它不检查目标缓冲区是否足够大以包含连接的结果字符串。如果目标不够大,无法容纳连接的结果字符串,那么它会导致未定义的行为,包括它可能执行不正确(崩溃或静默生成不正确的结果),或者它可能完全符合程序员的意图。

您应该指定足够大的缓冲区大小a以容纳连接的结果字符串。在您的程序中,源字符串bro!大小为4. 用源字符串的第一个字符strcat()覆盖目标null字符,同时将它们连接起来,并且在形成的新字符串的末尾包含一个空字符。因此,在您的情况下,保存连接的结果字符串所需的最小大小是9.

声明a为:

char a[9] = {'H','e','y','a','\0'};

应该可以正常工作。

正如大卫建议(在评论中)而不是9,您可以采用一些合理大小的缓冲区,例如512or 1024(例如a[512]or a[1024])。它可以帮助您在一定程度上避免问题。但是,您需要注意代码中的缓冲区溢出问题。例如,您可以使用strncat(),它使您可以灵活地指定可以附加到目标字符串中的最大大小。
您可以将要附加的最大字符数指定为 -

(size of destination buffer) - (the length of the destination string) - 1

以避免缓冲区溢出。

于 2018-02-16T06:29:11.920 回答