0

代码 1

int main()
{
    char str[]="abc";
    char str1[]="hello computer";
    strcat(str,str1);
    printf("the concatenated string is : %s\n",str);
    return 0;
}

输出-abchello computer

代码 2

int main()
{
    char str[100];  //notice the change from code 1
    char str1[]="hello computer";
    strcat(str,str1);
    printf("the concatenated string is : %s\n",str);
    return 0;
}

输出-@#^hello computer

代码 3

int main()
{
    char str[100];
    char str1[]="hello computer";
    strncpy(str,str1,5);
    str[5]='\0';   //external addition of NULL
    printf("the copied string is : %s\n",str);
    return 0;
}

输出-hello

代码 4

int main()
{
    char str[100]="abc";
    char str1[]="hello computer";
    strncat(str,str1,5);
    printf("the concatenated string is : %s\n",str);
    return 0;
}

输出-abchello

问题

Q-1) 为什么abchello computer会显示 incode 1@#^hello computerin code 2?垃圾@#^从哪里来?

Q-2) 为什么NULL '\0'需要外部添加strncpy()而不是分别strncat()显示在code 3code 4中?

注意 - 如果在code 4I do char str[100];then@#^hello中会显示,但字符串仍以不添加 NULL 的方式结束

4

4 回答 4

3

第一个示例写入超出 str 的末尾,因此具有未定义的行为。

第二个示例使用 strcat ,它需要两个以 null 结尾的字符串作为参数。您的其中一个参数不符合该要求,因为您未能对其进行初始化。

第三个示例不复制空终止符,因为 strncpy 就是这样设计的。从文档中可以看出,如果目标缓冲区小于源字符串,则 strncpy 不会写入空终止符。

至于第四个例子,strncat 与 strncpy 的不同之处在于它总是复制一个空终止符。

我建议您仔细参考这些函数的文档。

于 2014-01-22T17:45:52.457 回答
3

代码 1

char str[]="abc";
char str1[]="hello computer";
strcat(str,str1);

这溢出了str。行为是未定义的,可以假设任何输出(实际上,可能str1会被自身覆盖,这就是您将abshello computer其视为输出的原因)。

代码 2

char str[100];  //notice the change from code 1
char str1[]="hello computer";
strcat(str,str1);

您之前看到垃圾是hello computer因为str未初始化。碰巧它"@#^"在您的第一次 NUL 之前的测试时已经包含。

代码 3

char str[100];
char str1[]="hello computer";
strncpy(str,str1,5);
str[5]='\0';   //external addition of NULL

这是对的。strncpy复制前五个字符"hello computer"并且不以 NUL 终止它。你应该自己做(就像你做的那样)。如需进一步参考,请参阅手册页strcpy

strcpy()函数将src 指向的字符串,包括终止的空字节 ('\0') 复制到 dest 指向的缓冲区。字符串不能重叠,并且目标字符串 dest 必须足够大以接收副本。小心缓冲区溢出!(见错误。)

strncpy()函数类似,只是最多复制 n 个字节的 src 。警告:如果 src 的前 n 个字节中没有空字节,则放在 dest 中的字符串不会以空值结尾。

代码 4

char str[100]="abc";
char str1[]="hello computer";
strncat(str,str1,5);

strncpy和之间的一个区别strncatstrncatNUL 终止了结果字符串。从手册页strncat

与 strcat() 一样,dest 中的结果字符串始终以 null 结尾。

于 2014-01-22T17:49:44.557 回答
0

Q-1) 为什么代码1显示abchello computer,代码2显示@#^hello computer?垃圾@#^ 是从哪里来的?

在 Code2 中:“char str[100] 包含未初始化的垃圾字符”。

尝试多次运行 Code2 程序。您可能会看到每次运行时字符串开头的乱码都会发生变化。char str[100]在内存中保留一个位置,您可以在其中连续存储 100 个字符,但它不会为您清除它。以前程序在内存中留下的任何东西通常被称为“垃圾”。该内存几乎肯定包含上次使用内存时的随机数据。有时你甚至可以像这样在未初始化的内存中找到可读的字符串。

当你运行 strcat 时,程序需要找出 'str' 中字符串的结尾在哪里。问题是,从来没有一个合适的字符串放入 str - 它只是充满了垃圾。程序从 char str[100] 缓冲区的开头开始,并查找指示字符串结尾的 '\0' 字符。它最终会找到一个(随机的 '\0\ 最终会出现在内存中的某个位置)并声明它是第一个字符串的结尾。它现在将第一个 '\0' 之前的所有内容视为官方字符串的一部分。

strcat: str[0]='\0';试试这个:在程序现在应该运行而不显示乱码之前添加以下行。

于 2014-01-22T18:03:54.313 回答
0

正如大卫所说,对于 strcat 它期望以空结尾的字符串,因此这可能是垃圾值的可能原因。

对于您的代码 3,字符串末尾的 '\0' 字符将 char 数组表示为字符串,没有 '\0' 终止它只是一个 char 数组,而不是有效字符串。由于您使用 %s 进行打印,因此编译器需要将其作为字符串。

于 2014-01-22T17:54:18.997 回答