Strncpy没有像预期的那样工作

strncpy is not working as expected

本文关键字:工作 Strncpy      更新时间:2023-10-16
#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)] = '';
    cout<<c;
    return 0 ;
}

输出是:some random string。但我希望它是:some。有人能解释一下它为什么会这样吗?

它的工作只是很好-记住,strncpy不一定是空终止字符串。当你这样做时:

strncpy(c, token, 5);

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

c[strlen(c)] = '';

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

在新代码中,strncpy应该很少使用,如果有的话。它的预期用途(不一定以null结束的固定长度缓冲区)早就被忽略了。建议使用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)] = '';   // Does nothing
   cout<<c;
   return 0 ;
}

如果你想输出"some",你可以这样做:

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

strncpy()不会自动在dest字符串后面添加''。如果源字符串长度大于len (strncpy的第三个参数),则len字符不带''复制到dest。所以你必须通过代码显式地给出一个''。

您需要在单词"some"之后以空结束,而不是在整个字符串之后以空结束。Strncpy会将"some "复制到c中,但它不一定会以null终止字符串(参见Strncpy的手册页)

c[4] = ''

正如其他人所提到的,与snprintfsprintf不同,strncpy不是strcpy的更安全版本。它只是确保"精确地将N个字符复制到目标(如果源字符串短于N,则使用NUL)"。(手册页)

但是我想你已经注意到在

这一行
c[strlen(c)] = '';

表示确保c的null终止。但这实际上是毫无意义的,因为strlen使用NUL来确定c的长度。所以这一行的意思是"查找NUL并将NUL写入该位置"。

strncpy的重要性在于复制string的某一部分。它不是strcpy的修复,在snprintf函数引入之前就存在了。