Передать содержимое stringstream в функцию, принимая char* в качестве аргумента
У меня есть функция для записи файлов ppm (формат изображения) на диск. Он принимает имя файла как массив char*. В моей основной функции я собрал имя файла, используя поток строк и оператор <<. Затем я хочу передать результаты этого в мою функцию ppm. Я видел, что это обсуждалось в другом месте, часто с очень запутанными методами (многие промежуточные шаги преобразования).
То, что я сделал, показано в коде ниже, и сложная часть, которую другие обычно делают во многих шагах с временными переменными: (char*) (PPM_file_name.str().data())
, Это позволяет извлечь строку из строкового потока PPM_file_name с помощью.str(), затем получить указатель на ее фактическое содержимое с помощью.data() (это const char*), а затем преобразовать ее в обычный (char*). Более полный пример ниже.
До сих пор я обнаружил, что следующее работает нормально, но меня это беспокоит, потому что обычно, когда другие люди делают что-то более запутанное, это потому, что это более безопасный способ сделать это. Итак, кто-нибудь может сказать мне, если то, что я делаю здесь, безопасно, а также насколько оно портативно?
Благодарю.
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string>
using namespace std;
int main(int argc, char *argv[]){
// String stream to hold the file name so I can create it from a series of other variable
stringstream PPM_file_name;
// ... a bunch of other code where int ccd_num and string cur_id_str are created and initialized
// Assemble the file name
PPM_file_name << "ccd" << ccd_num << "_" << cur_id_str << ".ppm";
// From PPM_file_name, extract its string, then the const char* pointer to that string's data, then cast that to char*
write_ppm((char*)(PPM_file_name.str().data()),"ladybug_vidcapture.cpp",rgb_images[ccd_num],width,height);
return 0;
}
6 ответов
Это похоже на типичный случай, когда кто-то не пишет const-правильный код и у него есть эффект "зацепки". У вас есть несколько вариантов:
Если write_ppm находится под вашим контролем или под контролем кого-либо из ваших знакомых, попросите их сделать его более корректным
Если это не так, и вы можете гарантировать, что он никогда не изменит имя файла, тогда const_cast
Если вы не можете этого гарантировать, скопируйте вашу строку в std::vector плюс нулевой терминатор и передайте &vec[0] (где vec представляет имя вашей векторной переменной)
Спасибо всем. Итак, следуя советам нескольких людей, я сделал следующее, так как у меня есть контроль над write_ppm:
Модифицированный write_ppm для принятия const char*:
void write_ppm(const char *file_name, char *comment, unsigned char *image,int width,int height)
И теперь я передаю ppm_file_name следующим образом:
write_ppm((PPM_file_name.str().c_str()),"A comment",rgb_images[ccd_num],width,height);
Есть ли что-то, что я должен сделать здесь, или это в основном проясняет проблемы с тем, как это проходило раньше? Должны ли все остальные аргументы char для write_ppm быть константами? Это очень короткая функция, и она, похоже, не изменяет ни один из аргументов. Благодарю.
Это абсолютно безопасно и переносимо, если write_ppm фактически не меняет аргумент, и в этом случае это неопределенное поведение. Я бы порекомендовал использовать const_cast<char*>
вместо броска в стиле C Также рассмотрите возможность использования c_str()
член вместо data()
член. Первый гарантирует возврат строки с нулевым символом в конце
Вы должны использовать
PPM_file_name.str().c_str()
, посколькуdata()
не гарантируется возврат строки с нулевым символом в конце.Или
write_ppm()
должен принять свой первый аргументconst char*
(обещая не изменять содержимое строки) или вы не должны передавать поток строки (потому что вы не должны изменять его содержимое таким образом).
Вы не должны использовать приведения в стиле C в C++, потому что они не различают разные причины приведения. Твое изгнание const
, что, если вообще, должно быть сделано с помощью const_cast<>
, Но, как правило, const_cast<>
обычно требуется только для компиляции кода, который не const
-правильно, что я считаю ошибкой.
Почему бы просто не использовать const_cast<char *>(PPM_file_name.str().c_str())
?
Использование c_str()
вместо data()
(c_str()
вернуть NULL
-terminated sequence of characters).