使用 strcpy_s 将字符串复制到字符*
Using strcpy_s to copy string to char*
我知道当你使用strcpy_s时,你应该提供目标字符串的大小作为第二个参数。但是,如果目标字符串是字符*,那么我不确定我做得是否正确。我有三个例子:
char* dest = new char;
// Example 1
CString strTemp = "Bob";
strcpy_s(dest, strTemp.GetLength() + 1, strTemp);
// Example 2
strcpy_s(dest, strlen("Jose")+1, "Jose");
// Example 3
char* c = new char;
c = "Richard";
strcpy_s(dest, strlen(c) + 1,c);
这一切都正确吗?
在所有三个示例中,您传递的是源字符串的大小。您应该传递目标缓冲区的大小,以便strcpy_s
可以验证不会有缓冲区溢出。
传递源字符串的大小会破坏该检查。strcpy_s
已经知道源字符串的大小;它可以像你一样做strlen(src)
。它不能做的是自动检测目标缓冲区的大小。需要告诉它的大小。
const int SIZE = 2048; // an arbitrary large number
char* dest = new char[SIZE];
std::errno_t result = strcpy_s(dest, SIZE, src);
if (result != 0) {
// error
}
您的所有示例都应如下所示:
dest
指向的不是单个字符,而是大量字符数组。- 第二个参数是目标缓冲区的大小。
- 确保检查返回代码是否存在错误。
注意:尽可能避免在C++中使用 C 字符串。使用std::string
要好得多。它会为你处理所有这些混乱。您不必处理内存分配或担心缓冲区溢出。
请注意,您应该为目标分配正确的大小,因此请替换
分配一个字符的char* dest = new char;
由
char* dest = new char[strlen(strTemp)+1];
.
请注意,cString
不是一种类型,因此请替换CString strTemp = "Bob";
按char* strTemp = "Bob";
或const char* strTemp = "Bob";
(最后一个相当于auto strTemp = "Bob";
(。
请注意,c style string
s 不是objects
因此strTemp.GetLength()
无效。将其替换为strlen(strTemp)
并包含包含该函数的标头<cstring>
strlen()
。
最后,您的代码应如下所示
#include<iostream>
#include<cstring>
using namespace std;
int main(){
auto strTemp = "Bob";
char* dest = new char[strlen(strTemp)+1];
strcpy_s(dest, strlen(strTemp) + 1, strTemp);
cout<<dest;
}
这都是正确的吗?
没有一个例子是正确的。
char* dest = new char;
您已分配单个char
。它可以表示的唯一字符串是空字符串。
char* c = new char; c = "Richard";
通过将c
分配给其他位置的点,您丢失了new
返回的指针值。因此,您无法再将该值传递给delete
。这称为内存泄漏。
此外,由于 C++11 起,这是格式不正确的,因为字符串文字不再可转换为指向非常量字符的指针。 格式错误意味着编译器不需要编译程序,而是需要向您发出诊断消息,通知您格式不正确。
strcpy_s(dest, strlen(c) + 1,c);
您应该传递目标缓冲区的大小,而不是源数据的大小。在这种情况下,目标缓冲区太小,但由于您传递了错误的值,因此不会捕获错误,并且行为未定义。
正如我所提到的,传递目标缓冲区的大小:
auto error = strcpy_s(dest, 1, "Richard");
这安全地导致错误而不是未定义的行为 - 或者它可能安全地中止程序或根据实现执行其他操作。您可以控制约束处理程序以具有所需的行为。
当然,您可能希望分配足够的内存,以便副本正常工作:
std::size_t destsz = 1024;
char* dest = new char[destsz];
您知道分配的大小。只需将其传递给strcpy_s
:
auto error = strcpy_s(dest, destsz, "Richard");
不要忘记清理:
delete[] dest;
附言C++标准库不提供strcpy_s
。这是一个非标准功能。它仅在 C 语言中是标准的(但对于提供它的实现来说是可选的(。
PSS 不要使用new
来分配字符串。在C++中使用std::string
。使用std::string
您可以像这样复制:
std::string c = "Richard";
std::string dest = c;
使用这种方法泄漏内存或制造更严重的错误将更加困难。
如果在将字符串复制到其中之前分配内存,使用字符串复制函数会显示混乱的思维,导致公然浪费:只需使用memcpy()
(或std:copy_n()
(。
strcpy_s()
需要指向目标的指针、目标缓冲区大小和指向源的指针。
如果您猜测缓冲区大小是从源代码派生的缓冲区大小,而不是知道它,请使用strcpy()
而不是那种复杂的方式来(希望(编写相同的效率较低。
总之,你所有的使用都是错误的。
顺便说一句:new char
分配一个单独的char
,而不是一个适当大小的数组。请改用new char [n]
。
你真的需要复制字符串,还是实际上只是传递一个指针?
进程范围的约束处理程序不需要执行所需的操作。或者实际上任何有用的东西。
- 在这种情况下,我真的复制了字节还是复制了字符?
- 如何返回/复制unique_ptr<无符号字符[]>的值?
- 使用动态分配将 char* 复制到另一个字符**
- 库达如何将字符**从内核复制到主机
- 将字符向量复制到另一个向量
- 为什么我的代码在尝试复制字符数组时引发 C6386 错误?
- 使用 memcpy 函数C++复制字符数组
- 如何使用strncpy_s复制字符数组
- 在结构之间复制字符数据
- std::逐字节复制字符向量
- 比strncpy更好地复制字符阵列的部分方法
- 使用"="运算符复制字符* 内容
- 用 0 复制字符数组中的短整数
- 使用指针重新复制字符数组并修剪前导空格
- C++ 使用 char* 复制字符数组(无字符串库)
- 复制 c++ 字符指针
- 使用rd_buf复制C++字符串会更改const对象
- 如何从字符串指针复制字符到字符串向量
- 字符串字面值操作-复制字符
- 在使用std::copy而不是std::memcpy复制字符时避免libc函数调用