字符串转char*函数
string to char* function
对 c/c++ 很陌生。我对以下代码有疑问:
char* string2char(String command){
if (command.length() != 0) {
char *p = const_cast<char*>(command.c_str());
return p;
}
}
void setup() {}
void loop() {
String string1 = "Bob";
char *string1Char = string2char(string1);
String string2 = "Ross";
char *string2Char = string2char(string2);
Serial.println(string1Char);
Serial.println(string2Char);
}
这基本上是重复输出:
Ross
Ross
我明白我没能理解指针在这里是如何工作的概念 - 有人能解释一下吗?我该如何改变它才能显示:
Bob
Ross
这里的问题是您已按值将 String command
传递给函数,它会复制您传递给函数的任何 String
。因此,当您调用 const_cast<char*>(command.c_str());
时,您正在创建一个指向复制的 String
的 c 字符串的指针。由于您转换的 String
在函数范围内,因此当函数 returns 并且指针基本上无效时,内存将被释放。你想要做的是将参数更改为 String & command
,这将传递对字符串的引用,当函数 returns.
时,其内存不会被释放
你的问题围绕着你的论点展开。
char* string2char(String command){
// create a new string that's a copy of the thing you pass in, and call it command
if (command.length() != 0) {
char *p = const_cast<char*>(command.c_str());
// get the const char* that this string contains.
// It's valid only while the string command does; and is invalidated on changing the string.
return p; /// and destroy command - making p invalid
}
}
有两种方法可以解决这个问题。第一个也是最复杂的,是通过引用传递命令。因此 const String& command
然后使用它。
另一种方法更简单,就是完全删除您的函数;让你的 char*
const char*
并在字符串上调用 c_str()
;即
String string1 = "Bob";
const char *string1Char = string1.c_str();
正如 Mark Ransom 在评论中指出的那样,当您按值传递字符串时,字符串 command
是原始字符串的本地副本。因此你不能 return 指向它的 c_str()
的指针,因为那个指向本地副本,当函数完成时它会超出范围。因此,您会遇到与此处描述的相同的错误:How to access a local variable from a different function using pointers?
一个可能的解决方案是像这样重写函数:
const char* string2char(const String& command){
return command.c_str();
}
现在字符串通过引用传递,因此 c_str()
引用与调用方 (string1
) 中的相同的字符串对象。同时我还冒昧地修复了const-correctness
请注意,您不能通过 c_str()
编辑的指针 return 修改字符串!所以保持这个const
.
很重要
这个函数:
char* string2char(String command){
if (command.length() != 0) {
char *p = const_cast<char*>(command.c_str());
return p;
}
}
没有多大意义,它按值获取字符串和 returns 指向其内部缓冲区的指针,并用 constnes 封装(不要这样做)。当你返回已经被销毁的对象的值时,你会得到一些奇怪的行为,通过 ref 传递它。我也很好奇为什么你需要做所有这些事情,你不能直接通过:
Serial.println(string1.c_str());
Serial.println(string2.c_str());
对 c/c++ 很陌生。我对以下代码有疑问:
char* string2char(String command){
if (command.length() != 0) {
char *p = const_cast<char*>(command.c_str());
return p;
}
}
void setup() {}
void loop() {
String string1 = "Bob";
char *string1Char = string2char(string1);
String string2 = "Ross";
char *string2Char = string2char(string2);
Serial.println(string1Char);
Serial.println(string2Char);
}
这基本上是重复输出:
Ross
Ross
我明白我没能理解指针在这里是如何工作的概念 - 有人能解释一下吗?我该如何改变它才能显示:
Bob
Ross
这里的问题是您已按值将 String command
传递给函数,它会复制您传递给函数的任何 String
。因此,当您调用 const_cast<char*>(command.c_str());
时,您正在创建一个指向复制的 String
的 c 字符串的指针。由于您转换的 String
在函数范围内,因此当函数 returns 并且指针基本上无效时,内存将被释放。你想要做的是将参数更改为 String & command
,这将传递对字符串的引用,当函数 returns.
你的问题围绕着你的论点展开。
char* string2char(String command){
// create a new string that's a copy of the thing you pass in, and call it command
if (command.length() != 0) {
char *p = const_cast<char*>(command.c_str());
// get the const char* that this string contains.
// It's valid only while the string command does; and is invalidated on changing the string.
return p; /// and destroy command - making p invalid
}
}
有两种方法可以解决这个问题。第一个也是最复杂的,是通过引用传递命令。因此 const String& command
然后使用它。
另一种方法更简单,就是完全删除您的函数;让你的 char*
const char*
并在字符串上调用 c_str()
;即
String string1 = "Bob";
const char *string1Char = string1.c_str();
正如 Mark Ransom 在评论中指出的那样,当您按值传递字符串时,字符串 command
是原始字符串的本地副本。因此你不能 return 指向它的 c_str()
的指针,因为那个指向本地副本,当函数完成时它会超出范围。因此,您会遇到与此处描述的相同的错误:How to access a local variable from a different function using pointers?
一个可能的解决方案是像这样重写函数:
const char* string2char(const String& command){
return command.c_str();
}
现在字符串通过引用传递,因此 c_str()
引用与调用方 (string1
) 中的相同的字符串对象。同时我还冒昧地修复了const-correctness
请注意,您不能通过 c_str()
编辑的指针 return 修改字符串!所以保持这个const
.
这个函数:
char* string2char(String command){
if (command.length() != 0) {
char *p = const_cast<char*>(command.c_str());
return p;
}
}
没有多大意义,它按值获取字符串和 returns 指向其内部缓冲区的指针,并用 constnes 封装(不要这样做)。当你返回已经被销毁的对象的值时,你会得到一些奇怪的行为,通过 ref 传递它。我也很好奇为什么你需要做所有这些事情,你不能直接通过:
Serial.println(string1.c_str());
Serial.println(string2.c_str());