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)] = ' ';
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] = ' '
正如其他人所提到的,与snprintf
到sprintf
不同,strncpy
不是strcpy
的更安全版本。它只是确保"精确地将N个字符复制到目标(如果源字符串短于N,则使用NUL)"。(手册页)
但是我想你已经注意到在
这一行c[strlen(c)] = ' ';
表示确保c
的null终止。但这实际上是毫无意义的,因为strlen
使用NUL来确定c
的长度。所以这一行的意思是"查找NUL并将NUL写入该位置"。
strncpy
的重要性在于复制string的某一部分。它不是strcpy
的修复,在snprintf
函数引入之前就存在了。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- strncpy和strcat的工作方式与我认为的c++不同
- Strncpy没有像预期的那样工作