我在C中有以下程序:
该程序的主要问题是,在执行复制操作后,复制的字母后会显示许多垃圾字符。我知道这是因为目标变量没有正确地以null结尾。但是,如果仔细检查代码,我将执行空终止。为什么问题仍然存在?
答案 0 :(得分:8)
那么,呃,您认为strlen()
如何计算字符串的长度?你认为它需要终止吗?
提示:确实如此。字符数组不是C中的字符串,除非它以0字符结尾。所有strlen()
都会计算字符数,直到它找到终结符,因此在逻辑中使用它来终止缓冲区以使其成为字符串是鸡蛋类的情况。
您的问题是您误用strncpy()
。这是一个非常容易做错的事情,因为从典型的(初学者)C程序员的角度来看,这个功能稍微有点疯狂。从名称来看,它根本不能达到你所期望的效果。
您可能只需手动执行此操作,只要您确定nob < sizeof destination - 1
:
memcpy(destination, source, nob);
destination[nob] = '\0';
答案 1 :(得分:5)
Matthew,当您已经知道要复制的字符串的长度时,您不需要strcpy
或strncpy
(它会检查每个字符在末尾查找\ 0)。相反,您应该使用memcpy
然后终止新字符串:
memcpy(destination, source, nob);
destination[nob] = '\0';
memcpy
不会检查'\ 0',所以更快。
答案 2 :(得分:4)
而不是:
destination[strlen(destination)] = '\0';
有:
destination[nob] = '\0';
strlen
继续阅读,直到找到'\0'
字符。
答案 3 :(得分:2)
strncpy
不保证您的destination
字符串在复制后将以空值终止。我的方法是:
destination[ nob ] = '\0';
答案 4 :(得分:1)
经过一些非常小的修改后,这将很有效:
char destination[18] = {'\0'};
答案 5 :(得分:1)
不要使用strncpy,这很危险。正如我们从您的示例中看到的那样,程序员总是忘记向其输入正确的参数,因此他们会得到损坏的字符串。这是一个非常常见的错误。
strcpy()更安全,但也不理想,因为它没有边界检查。如果使用不当,可能会导致缓冲区溢出,这是一个安全问题。这也是一个常见的错误。
复制字符串的最快最安全的方法是通过memcpy:
memcpy(destination, source, nob);
desitnation[nob] = '\0';
答案 6 :(得分:0)
这是失败的,因为 strncpy 仅复制第一个 nob 字符,并且不附加尾随 0 。您尝试在目标字符串上添加带有 strlen()的尾随0无效,因为它会计算字符直到第1个0,并在该位置放置零(这将不起作用)
“破解”修复方法的一种方法是清除目标字符串:
memset( destination, 0, sizeof(destination));
可能有更好的解决方案,包括为&gt;进行测试17 &gt; 18 强>