C++ strncpy未按预期工作 #包括 使用名称空间std #包括 int main(){ 字符标记[]=“一些随机字符串”; charc[23]; strcpy(c,token); strncpy(c,token,5); c[strlen(c)]='\0'; cout

C++ strncpy未按预期工作 #包括 使用名称空间std #包括 int main(){ 字符标记[]=“一些随机字符串”; charc[23]; strcpy(c,token); strncpy(c,token,5); c[strlen(c)]='\0'; cout,c++,string,strncpy,C++,String,Strncpy,您需要在单词“some”之后以null结尾,而不是在整个字符串之后以null结尾。strncpy会将“some”复制到c中,但它不一定以null结尾字符串(有关详细信息,请参阅手册页) 它工作得很好。请记住,当您这样做时: c[4] = '\0' 它将token的前5个字节复制到c中,但不会以null终止结果。此外,此行没有用处: strncpy(c, token, 5); strlen(c)查找现有的空终止符,一旦找到一个,就用另一个空终止符覆盖它,这是毫无意义的 在新代码中,strncp

您需要在单词“some”之后以null结尾,而不是在整个字符串之后以null结尾。strncpy会将“some”复制到c中,但它不一定以null结尾字符串(有关详细信息,请参阅手册页)


它工作得很好。请记住,当您这样做时:

c[4] = '\0'
它将
token
的前5个字节复制到
c
中,但不会以null终止结果。此外,此行没有用处:

strncpy(c, token, 5);
strlen(c)
查找现有的空终止符,一旦找到一个,就用另一个空终止符覆盖它,这是毫无意义的

在新代码中,
strncpy
应该很少被使用。它的预期用途(不一定以null结尾的固定长度缓冲区)早就被禁止了。相反,我们更喜欢类似这样的函数(注意:
strlcpy
不是标准的;它只在类似BSD的系统中可用)


或者,如果你用C++来代替纯C,只需使用<代码> STD::String 并避免像这样棘手的问题。

< P>我认为你的输出应该是“一些随机字符串”,因为你的两行代码不做任何事情,请看评论。
c[strlen(c)] = '\0';

strncpy()不会自动将尾部“\0”添加到dest字符串。如果源字符串长度大于len(strncpy的第三个参数),然后将len个字符复制到dest,而不带尾随“\0”。因此,您必须通过代码显式地给出尾随“\0”。

正如其他人所提到的,与
snprintf
sprintf
不同,
strncpy
不是
strcpy
的更安全版本。它只是确保“恰好N个字符被复制到目的地”(如果源字符串小于N,则使用NUL)”(手册页)

但我想你已经注意到了

strncpy(c, token, 5);
c[5] = '\0';
它的意思是确保
c
的空终止。但是它实际上是没有意义的,因为
strlen
使用NUL来确定
c
的长度。所以这一行仅仅意味着“查找NUL并将NUL写入该位置”


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

我建议在strncpy(c,token,5)之后使用
std::string
,已执行,c的值应该是一些。如果我错了,请更正。strncpy()不会自动将尾部“\0”添加到dest字符串。如果源字符串长度大于len(strncpy的第三个参数),然后最多复制到dest的len个字符,而不拖尾“\0”。因此,您必须通过代码显式地给出拖尾“\0”。如果必须显式地给出“\0”。那么,我可以通过使c[4]=“\0”而不调用strncpy(…)来获得一些输出。那么strncpy(…)的重要性是什么;strncpy用于确保dest缓冲区不溢出。strcpy不关心dest缓冲区有多大,它不会停止将字符复制到dest,直到找到一个“\0”。这个答案应该被授予奖章!谢谢。如果我必须明确地给出“\0”。那么我可以通过使c[4]=“\0”而不调用strncpy(..)来获得一些输出StrncPy(…)的重要性是什么?StrncPy的重要性是避免缓冲区溢出。想想如果目标缓冲区小于源字符串,会发生什么。虽然我推荐了第二个。如果这是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 ;
}
strncpy(c, token, 5);
c[5] = '\0';
c[strlen(c)] = '\0';