如何将常量字符*存储到字符*
How to store a const char* to a char*?
我有这段代码可以按预期工作:
#define MAX_PARAM_NAME_LEN 32
const char* GetName()
{
return "Test text";
}
int main()
{
char name[MAX_PARAM_NAME_LEN];
strcpy(name, GetName());
cout << "result: " << name << endl;
}
如果我想将结果存储到char *
(因为我使用的框架中的某些函数仅使用char *
作为输入)而不使用strcpy
(为了代码的实用性和可读性,以及学习),我该怎么办?保持const
,这很有效:
const char* name;
name = GetName();
但我还有const
.
尝试只使用char*
:
char* name;
name = GetName();
我得到invalid conversion from 'const char*' to 'char*'
.这种转换的最佳习惯是什么?
这种转换的最佳习惯是在整个代码中使用std::string
。由于您使用的框架将const char*
作为其输入,因此您始终可以向其传递c_str()
调用std::string
的结果:
std::string GetName() {
return "Test text";
}
int main() {
std::string name = GetName();
int res = external_framework_function(name.c_str());
cout << "result: " << res << " for " << name << endl;
}
第二好的方法是在代码中使用const char*
:
const char* name = GetName();
由于您使用的框架需要const char*
因此您在这里也很好。
如果需要非常量指针,则无法复制字符串。您可以创建一个为您执行此操作的函数,但您仍然负责释放从中获得的副本:
char* copy(const char* orig) {
char *res = new char[strlen(orig)+1];
strcpy(res, orig);
return res;
}
...
char *name = copy(GetName());
...
delete[] name;
>return "Test text";
返回指向只读字符串文本的指针。
如果您使用的函数将char*
作为输入,并且您有一个const char*
(例如只读字符串文本),那么您应该向此类函数提供从该const char*
开始的字符串的深层副本。
否则,如果函数尝试修改只读字符串,则在运行时存在未定义行为的风险。
你目前拥有的已经足够了;假设你不能与std::string
一起工作。(如果你可以使用std::string
并且你的所有框架函数都接受const char*
输入,那么我建议你重构你的代码以使用std::string
,并将该字符串类上的c_str()
方法的输出传递给你的框架函数。
最后,如果你的某些框架函数需要char*
那么你总是可以为自己构建一个小的适配器类:
class Adapter
{
public:
Adapter(const& Adapter) = delete; /*don't try to copy me please*/
Adapter& operator=(const Adapter& ) = delete; /*don't try to copy me please*/
Adapter(const char* s) : m_s(::strdup(s))
{
}
~Adapter() /*free memory on destruction*/
{
::free(m_s); /*use free to release strdup memory*/
}
operator char*() /*implicit cast to char* */
{
return m_s;
}
private:
char* m_s;
};
然后对于函数void foo(char* c)
,您可以调用foo(Adapter("Hello"/*or any const char* */));
,foo
可以随心所欲地使用嵌入在匿名临时中的char*
!您甚至可以增强此类以将构造函数带到一个char*
在这种情况下,仅获取指针的浅表副本(析构函数不会删除内存)。
在C++中,"删除const
"的典型方法是使用const_cast<>
:
char *name = const_cast<char*>(GetName());
当然,这是不受欢迎的,丑陋的和潜在的危险,因为GetName()
确实有可能返回一个指向不应该更改的内容的指针,然后你去允许自己更改它。在这种情况下,这是很难找到错误的好方法。
解决方法是使用 std::string
作为临时保留区域;这意味着复制字符串,但这在性能方面可能是可以接受的:
std::string s(GetName());
char *name = s.c_str();
当然,只有在s
超出范围时不保留name
的情况下,这才有效。如果是这种情况,那么你将拥有某种形式的持久字符串存储层。
你可以显式转换它。 (char*) getName()
.但你可能不应该。因为const
位的意思是"承诺不改变它"。因此,如果我有一个函数void foo(const char* string)
我正在搜索:"给我一个指向字符串的指针。我不会改变它。如果你声明一个变量const char* string = "hello";
你说,这个字符串不应该被改变。而且因为你做出了这个承诺,编译器知道,并且可以让你的代码更有效率。这就是为什么:
const char* a = "hello";
const char* b = "hello";
(a==b); //is probably true
编译器知道您不会更改a
或b
因此会使它们指向同一地址,因此它只需要存储一个"hello"
字符串。如果你现在去改变a
,b
也会改变,这不是你想要的。
长话短说,如果你绝对确定你调用的函数不会改变字符串,你可以显式地强制转换它。(或者更好的是,如果函数是你的,请将函数更改为(const char*)
)。
如果您不确定,则必须复制一份(就像您已经在对strcpy()
所做的那样)。
- 使用无符号字符数组有效存储内存
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 我的目标是编写一个程序来计算和存储字符串在字符数组中出现的位置
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 按字母顺序打印存储在字符数组中的信息
- std::bad_alloc 将文本文件中的单个字符存储到矢量C++中时
- 如何使用 std::cin 将字符 ú 存储在字符数组中?
- 将 Unicode 字符存储在.txt文件中的新行中
- 将字符存储在C 树中
- 如何将常量字符*存储到字符*
- C/C++ - 将文件中的字符存储到 2d 字符数组中
- Pep/8 汇编 - 将字符存储在变量中而不输入
- 如何解析用户的输入并将每个单独的字符存储为字符串
- 将字符存储在用字符串初始化的字符指针中
- std::string是否需要将其字符存储在连续的内存中?< / h1 >
- 将字符串的每个字符存储到数组中(c++)
- 将单个字符存储到队列<string>:错误
- 用c++将无符号字符存储为二进制文件
- 将Ascii字符存储在c++中的数组中
- 如何读取西班牙语编码的文件并逐个字符存储