strcpy () not working properly
我目前正在编写一个程序,我被困在strcpy()函数的另一种行为中。以下是它的简短演示…
我回答了以下问题:从C字符串中去掉第一个和最后一个字符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| //This program checks whether strcpy() is needed or not after doing the modification in the string
#include <stdio.h>
#include <string.h>
int main ()
{
char mystr [] ="Nmy stringP";
char *p = mystr ;
p ++;
p [strlen(p )-1] = '\0';
strcpy(mystr ,p );
printf("p : %s mystr: %s
",p ,mystr );
} |
输出:
1
| p : y strnng mystr: my strnng |
号
如果我不使用strcpy()函数,那么我得到
1
| p : my string mystr : Nmy string |
为什么会这样??
- 我认为你不能使用来源和目的地重叠的strcpy。
- 不能为strcpy()源缓冲区和目标缓冲区重叠内存。如果您这样做,行为是未定义的。请参阅文档。
- 在你进入更深层次之前的一般提示:永远不要使用strcpy。它是太多坏代码和太多系统漏洞的根源。最好是strncpy。
- memcpy()更可取,memmove()或重叠。不管怎样,这两种方法都会迫使您执行最终总是使用strncpy()执行的操作:即硬终止目标缓冲区。srtncpy()很好(我经常使用它),但是知道它是如何工作的(即它总是精确地写n字符,而不是更多)是很重要的。
- @marcb:strcpy不是系统漏洞的来源;糟糕的系统设计是系统漏洞的来源…而strncpy也不排除在不良的系统设计中。使用strncpy可以引入一类新的漏洞:由于缺少'\0'终止而导致的信息披露。在设计良好的算法中使用strcpy完全没有问题。
- @modifiablelvalue:至少对于strncpy,您不必希望使用空终止符。您可能仍然会丢弃一些东西,但最多只能使用n字节的值,而不是strcpy可能使用的0->max-int范围。
- @marcb strncpy不一定会产生字符串,这就是您的建议的问题所在。不要让人们相信这是真的。你不能给未定义的行为下定义。
- 先生,根据文档,当对象重叠时,strncpy仍然会给出未定义的行为,因此这也不能解决问题……我想……
- @马克:斯特伦奇绝对不可取。Strncpy是一个死亡陷阱。如果没有足够的空间,它将产生一个无效字符串的结果。当复制UTF-8字符串时,它可能会产生无效的结果,而UTF-8字符串占大型字符串用例的很大一部分。有strlcpy,但最好的方法是让代码为结果分配足够的内存。
标准规定:
7.24.2.3
If copying takes place between objects that overlap, the behavior is
undefined.
号
您可以同时使用memmove或其他方法。
如果源字符串和目标字符串重叠,则不能使用内存位置重叠的strcpy。在这种情况下,行为是未定义的,如标准中所述。
但是您可以使用temp内存位置来进行这样的交换