如何避免 strcpy_s 缓冲区太小
Posted
技术标签:
【中文标题】如何避免 strcpy_s 缓冲区太小【英文标题】:How to avoid strcpy_s buffer too small 【发布时间】:2014-10-10 21:53:20 【问题描述】:我需要将std::string data
复制到一个字符数组中。我的字符串的长度是可变的,但我的 char 数组的长度是固定的。
const int SIZE = 5;
char name[SIZE];
std::string data = "1234567890";
strcpy_s(name, 5, data.c_str()); //causes a buffer is too small assertion
strcpy_s(name, 11, data.c_str());//copies fine (length of data plus null)
strcpy_s(name, sizeof(data), data.c_str()); // copies fine
如何每次只安全地复制数组的长度?没有得到断言,也没有导致缓冲区溢出。
我应该每次都这样吗?
std::string toCopy = data.substr(0,SIZE-1);
strcpy_s(name, toCopy.c_str());
【问题讨论】:
如果这是C++11,你可以只使用字符串的缓冲区。 是的,它的 C++ll。你能举个例子说明你的意思吗?? 如果你的意思是“mstrcpy_s(name, data.c_str());”这给了我想要避免的断言错误。 只需执行s2 = s1;
(或需要的子字符串),而不是使用 C 字符串。当您需要字符指针时,使用&s2[0]
表示可修改的指针,直到最后一个空终止符之前,或使用c_str()
表示不可修改的指针。
【参考方案1】:
将strncpy_s 与_TRUNCATE
一起使用
例如:
strncpy_s(name, data.c_str(), _TRUNCATE);
将尽可能多地复制以填充 name
缓冲区,同时仍将空终止考虑在内(与传统的 strncpy 不同)。
【讨论】:
【参考方案2】:以下内容返回 ERANGE 结果,因为您必须为终止 NULL 字符留出空间。变量“数据”包含 10 个元素。当 strcpy_s 达到约束 '5' 时,它无法找到终止 NULL 并返回 ERANGE。
strcpy_s(name, 5, data.c_str());
Microsoft Documentation
strcpy_s函数复制strSource地址中的内容, 包括终止空字符,到的位置 由 strDestination 指定。目标字符串必须很大 足以容纳源字符串及其终止空字符。 如果源和目标未定义 strcpy_s 的行为 字符串重叠。
替代方法
string data = "0123456789";
int SIZE = 5;
char name[SIZE];
size_t length = data.copy( name, 0, 5 );
buffer[ length ] = '\0';
【讨论】:
谢谢,这对我有用。我有足够的空间存放字符串,但没有复制nullchar
。真的很奇怪的行为,而且绝对是一个奇怪的错误信息。以上是关于如何避免 strcpy_s 缓冲区太小的主要内容,如果未能解决你的问题,请参考以下文章
执行动态SQL报“字符串缓冲区太小”错误,请问各位高手怎么解决啊