繁体   English   中英

strncpy无法正常工作

[英]strncpy is not working as expected

#include <iostream>
using namespace std 
#include <string.h>
int main(){
    char token[] = "some random string";
    char c[23];  
    strcpy( c, token);
    strncpy(c, token, 5); 
    c[strlen(c)] = '\0';
    cout<<c;
    return 0 ;
}

我的输出是: some random string 但我希望它是: some 任何人都可以解释为什么它会这样吗?

它工作得很好,请记住, strncpy不必对字符串进行null终止 执行此操作时:

strncpy(c, token, 5);

它将token的前5个字节复制到c 但不对结果进行空终止 此外,此行是无用的:

c[strlen(c)] = '\0';

strlen(c)查找现有的空终止符,一旦找到一个空终止符,便用另一个无意义的空终止符覆盖它。

在新代码中, 很少使用strncpy 它的预期用途(固定长度的缓冲区不一定是空终止的)早就被淘汰了。 最好改用诸如strlcpy类的函数(注意: strlcpy不是标准的;它仅在类似BSD的系统中可用)。

或者,如果您使用C ++而不是纯C进行编码,则只需使用std::string并完全避免此类棘手的问题。

我认为您的输出应该是“一些随机字符串”,因为您的两行代码什么都不做,请参见注释。

int main(){
   char token[] = "some random string";
   char c[23];  
   strcpy( c, token);
   strncpy(c, token, 5);  // Does nothing
   c[strlen(c)] = '\0';   // Does nothing
   cout<<c;
   return 0 ;
}

如果要输出“ some”,则可以执行以下操作:

strncpy(c, token, 5);
c[5] = '\0';

strncpy()不会自动在目标字符串中添加尾随“ \\ 0”。 如果源字符串的长度大于len(strncpy的第三个参数),则将len个字符复制到dest中,而不以'\\ 0'结尾。 因此,您必须通过代码明确给定尾随“ \\ 0”。

您需要在单词“ some”之后使null终止,而不是在整个字符串之后使null终止。 strncpy会将“ some”复制到c中,但不一定将null终止您的字符串(有关strncpy,请参见手册页)

c[4] = '\0'

正如其他人提到的那样,与snprintfsprintf不同, strncpy并不是strcpy的安全版本。 它仅确保“恰好将N个字符复制到目标位置(如果源字符串短于N,则使用NUL)”。 (手册页)

但我认为您已经注意到这一点

c[strlen(c)] = '\0';

这意味着确保c的空终止。 但这实际上是没有意义的,因为strlen使用NUL来确定c的长度。 因此,这行几乎不意味着“找到NUL并将NUL写入该位置”。

strncpy的重要性是复制字符串的certian部分。 它不是对strcpy的修复,并且在引入snprintf函数之前就已存在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM