функция string to char * - PullRequest
       34

функция string to char *

0 голосов
/ 18 мая 2018

Совершенно новый для 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

Ответы [ 4 ]

0 голосов
/ 18 мая 2018

Эта функция:

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

Не имеет особого смысла, она принимает строку по значению и возвращает указатель на свой внутренний буфер с удаленными константами (не делайте этого).Вы получаете какое-то странное поведение, так как вы возвращаете значения объекта, который уже был уничтожен, передавайте его по ссылке ref.Также мне любопытно, почему вы должны делать все это, не могли бы вы просто передать:

Serial.println(string1.c_str());
Serial.println(string2.c_str());
0 голосов
/ 18 мая 2018

Ваша проблема вращается вокруг вашего аргумента.

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

Есть 2 способа решить эту проблему.Первый и самый сложный, это передать команду по ссылке.Таким образом, const String& command и затем работа с этим.

Альтернативой, которая намного проще, является полное удаление вашей функции;наберите char* const char* и просто наберите c_str() в строке;т.е.

String string1 = "Bob";
const char *string1Char = string1.c_str();
0 голосов
/ 18 мая 2018

Как отметил Марк Рэнсом в комментариях, когда вы передаете строку по значению, строка command является локальной копией исходной строки.Поэтому вы не можете вернуть указатель на его c_str(), потому что он указывает на локальную копию, которая выйдет из области видимости после завершения функции.Таким образом, вы получаете ту же ошибку, как описано здесь: Как получить доступ к локальной переменной из другой функции с помощью указателей?

Возможное решение - переписать функцию следующим образом:

const char* string2char(const String& command){
  return command.c_str();
}

Теперь строка передается по ссылке, так что c_str() ссылается на тот же строковый объект, что и объект в вызывающей стороне (string1).Я также позволил себе исправить константность одновременно.

Обратите внимание, что вы не можете изменить строку указателем, возвращаемым c_str()!Поэтому очень важно сохранить это const.

0 голосов
/ 18 мая 2018

Проблема в том, что вы передали String command в функцию по значению, которая делает копию того, что String вы передали в функцию.Итак, когда вы вызываете const_cast<char*>(command.c_str());, вы делаете указатель на строку c скопированного String.Поскольку приведенный вами String находится внутри области действия функции, память освобождается, когда функция возвращается, и указатель по существу недействителен.Что вы хотите сделать, это изменить аргумент на String & command, который будет передавать ссылку на строку, чья память не будет освобождена, когда функция вернется.

...