int main()
{
char str[]="abc";
char str1[]="hello computer";
strcat(str,str1);
printf("the concatenated string is : %s\n",str);
return 0;
}
abchello computer
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
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
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
问题1)为什么abchello computer
和code 1
@#^hello computer
中显示code 2
?垃圾@#^
来自哪里?
问题2)为什么在NULL '\0'
中需要strncpy()
而在strncat()
中不需要外部添加code 3
,分别在code 4
和code 4
中显示?
char str[100];
中我@#^hello
,则会显示{{1}},但字符串结束时不添加NULL 答案 0 :(得分:3)
第一个示例写入超出str的结尾,因此具有未定义的行为。
第二个例子使用strcat,它要求两个以null结尾的字符串作为参数。你的一个论点不符合这个要求,因为你没有初始化它。
第三个示例不复制空终止符,因为这是strncpy的设计方式。从文档中可以看出,如果目标缓冲区小于源字符串,strncpy不会写入空终止符。
至于第四个例子,strncat与strncpy的不同之处在于它总是复制一个空终止符。
我建议您仔细参考这些功能的文档。
答案 1 :(得分:3)
char str[]="abc";
char str1[]="hello computer";
strcat(str,str1);
这会溢出str
。行为是未定义的,可以假设任何输出(实际上,可能str1
被自己覆盖,这就是你将abshello computer
视为输出的原因。
char str[100]; //notice the change from code 1
char str1[]="hello computer";
strcat(str,str1);
您在hello computer
之前看到垃圾,因为str
未初始化。它恰好在你的第一个NUL之前的测试时包含了"@#^"
。
char str[100];
char str1[]="hello computer";
strncpy(str,str1,5);
str[5]='\0'; //external addition of NULL
这是对的。 strncpy
复制"hello computer"
中的前五个字符,但不会终止它。你应该自己做(就像你做的那样)。有关进一步参考,请参阅strcpy
的手册页:
strcpy()函数将src指向的字符串(包括终止空字节('\ 0'))复制到dest指向的缓冲区。字符串可能不重叠,目标字符串dest必须足够大才能接收副本。小心缓冲区溢出! (见BUGS。)
strncpy()函数类似,只是复制了最多n个字节的src。 警告:如果src的前n个字节中没有空字节,则放在dest中的字符串将不会以空值终止。
char str[100]="abc";
char str1[]="hello computer";
strncat(str,str1,5);
strncpy
和strncat
之间的一个区别是strncat
NUL - 终止生成的字符串。来自strncat
的手册页:
与strcat()一样,dest中的结果字符串始终以null结尾。
答案 2 :(得分:0)
正如大卫所说,对于strcat,它期望以null结尾的字符串,以便可能是垃圾值的原因。
对于你的代码3,字符串最后的'\ 0'字符表示一个char数组作为字符串,out'\ 0'终止它只是一个char数组而不是一个有效的字符串。由于您使用%s进行打印,因此编译器需要将其作为字符串。
答案 3 :(得分:0)
Q-1)为什么abchello计算机显示在代码1和@#^ hello中 电脑在代码2?从哪里垃圾@#^来了?
在Code2中:“char str [100]包含未初始化的垃圾字符”。
尝试多次运行Code2程序。您可能会看到每次运行时字符串开头的乱码都会发生变化。 char str[100]
在内存中保留一个位置,您可以连续存储100个字符,但不会为您清除它。从以前的程序留在内存中的任何东西通常被称为“垃圾”。该内存几乎肯定包含上次使用内存时的随机数据。有时您甚至可以在未初始化的内存中找到可读字符串。
当你运行strcat时,程序需要找出'str'中字符串结尾的位置。问题是,从来没有一个正确的字符串放入str - 它只是充满了垃圾。程序从char str [100]缓冲区的开头开始,查找表示字符串结尾的'\ 0'字符。它最终会找到一个(随机的'\ 0 \最终会出现在内存中的某个地方)并声明它是第一个字符串的结尾。它现在认为第一个'\ 0'之前的所有内容都是官方字符串的一部分。
试试这个:在strcat: str[0]='\0';
之前添加以下行。程序现在应该运行而不显示乱码。