【发布时间】:2021-07-23 23:59:23
【问题描述】:
我正在测试一些string.h 函数,发现在使用函数strncpy 和strncat 时出现了奇怪的行为。
#include <stdio.h>
#include <string.h>
int main()
{
char name1[30], name2[30], name3[30], name4[30], name5[30];
char *res;
printf("First name: ");
scanf("%[^\n]", name1);
setbuf(stdin, NULL);
printf("\nSecond name: ");
scanf("%[^\n]", name2);
strcpy(name3, name2);
printf("\nname3: %s", name3);
strncpy(name4, name3, 5);
printf("\nname4: %s", name4);
//printf("\nSize of first name: %zu", strlen(nome1)); //zu para size_t
//printf("\nTamanho do segundo nome: %d", (int) strlen(nome2));
strncpy(name5, name1, 3);
printf("\nname1: %s", name1);
printf("\nname2: %s", name2);
printf("\nname3: %s", name3);
printf("\nname4: %s", name4);
printf("\nname5: %s", name5);
strcat(name1, name2);
printf("\nname1: %s", name1);
strncat(name4, name5, 3);
printf("\nname4: %s", name4);
return 0;
}
当我运行代码时,我得到以下输出:
First name: apple
Second name: elefant
name3: elefant
name4: elefa
name1: apple
name2: elefant
name3: elefant
name4: elefa
name5: app|�
name1: appleelefant
name4: elefaapp
为什么name5 得到app|� 而不是仅仅得到app?此外,有时我得到最后一个name4,它是name4 与name5 的串联,为elefaapp|�。谁能解释一下这种奇怪的行为吗?
我已经搜索并阅读了函数文档,但我对此一无所知。
【问题讨论】:
-
你忘了空终止
name5,所以它包含'a'、'b'、'c',后面是垃圾。在strncat调用后添加name5[3] = '\0';以修复它。 -
strncpy不会在字符串中添加空终止符,因此您会在name5中得到垃圾。在任何strncpy尝试之前使用memset(dest, '\0', sizeof(dest));。 -
正如
strncpy文档中所说,“...最多复制 n 个字节的 src。警告:如果 src 的前 n 个字节中没有空字节,则放置的字符串in dest 不会以 null 结尾。”您需要输入一个终止空字符。 -
@DaltonCézane 你从未将
name5传递给fgets或scanf。问题不在于name1。这是name5。name5中的初始值未定义。然后,您将其传递给长度为 3 的strncpy。这定义了name5的前三个值,其余值保留其原始未定义值。所以在调用之后,name5包含三个已定义的值,后跟 27 个未定义的值。如果要使用strncpy设置name5,则必须确保将最后一个复制值之后的第一个值设置为'\0'。你忘了这样做。 -
问题不是
name1或者是如何获取的。问题是name5及其未定义的内容。