字符串到字符*函数 对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); }

字符串到字符*函数 对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); },c++,pointers,arduino,c-strings,C++,Pointers,Arduino,C Strings,我知道我没有理解指针在这里是如何工作的——有人能解释一下吗?我将如何改变这一点,使其能够显示: Bob Ross 这里的问题是,您已经通过值将String命令传递给了函数,这将复制传递给函数的任何String。因此,当您调用const_cast(command.c_str())时您正在创建一个指向复制的字符串的c字符串的指针。由于您所转换的字符串在函数的作用域内,因此当函数返回且指针基本无效时,内存将被释放。您要做的是将参数更改为String&command,这将传递对字符串的引用,当函数返回

我知道我没有理解指针在这里是如何工作的——有人能解释一下吗?我将如何改变这一点,使其能够显示:

Bob
Ross

这里的问题是,您已经通过值将
String命令
传递给了函数,这将复制传递给函数的任何
String
。因此,当您调用
const_cast(command.c_str())时
您正在创建一个指向复制的
字符串的c字符串的指针。由于您所转换的
字符串
在函数的作用域内,因此当函数返回且指针基本无效时,内存将被释放。您要做的是将参数更改为
String&command
,这将传递对字符串的引用,当函数返回时,字符串的内存将不会被释放。

您的问题围绕着参数

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
    }
}

正如Mark Ransom在注释中指出的,当您按值传递字符串时,string
命令
是原始字符串的本地副本。因此,您不能返回指向其
c_str()
的指针,因为该指针指向本地副本,该副本在函数完成时将超出范围。因此,您会得到与此处所述相同的错误:

一种可能的解决方案是重写函数,如下所示:

const char* string2char(const String& command){
  return command.c_str();
}
现在字符串通过引用传递,以便
c_str()
引用与调用者中的字符串对象相同的字符串对象(
string1
)。同时,我还随意修改了const的正确性

请注意,您不能通过
c_str()
返回的指针修改字符串!因此,保持此
常量非常重要

此函数:

char* string2char(String command){
    if (command.length() != 0) {
        char *p = const_cast<char*>(command.c_str());
        return p;
    }
}

@我不知道该怎么做。我假设这里的
String
相当于
std::String
。未定义的行为-您正在按值传递
String
,它在函数末尾被销毁。@MarkRansom当然了。很好,你应该把它作为问题的答案贴出来。除非在某个地方有一个很好的标准副本。出于好奇,这个的实际用例是什么?只是学习指针?你为什么抛弃康斯特内斯?不要这样做。也不需要检查长度0。我被这段代码弄糊涂了:
我不知道它是如何编译std的,没有字符串类型,但是字符串
这被标记为
Arduino
,它使用自己的
字符串
对象,幸运的是它有
.c_str()
method,他希望
char*
处于可修改状态,否则这个函数就完全多余了,只需在适当的位置使用
c_str()
。在这一点上,设计变成了一个问题,为什么您需要一个
char*
const char* string2char(const String& command){
  return command.c_str();
}
char* string2char(String command){
    if (command.length() != 0) {
        char *p = const_cast<char*>(command.c_str());
        return p;
    }
}
Serial.println(string1.c_str());
Serial.println(string2.c_str());