我有一个将ppm文件(图片格式)写入磁盘的功能。它将文件名作为char *数组。在我的main函数中,我使用stringstream和<<组合了一个文件名。运营商。然后,我想将此结果传递给我的ppm函数。我已经在其他地方看到过这种情况,通常采用非常复杂的方法(许多中间转换步骤)。
我所做的工作在下面的代码中显示,其他人通常在临时变量的许多步骤中执行的棘手部分是(char*) (PPM_file_name.str().data())
。这样做是通过.str()从stringstream PPM_file_name中提取字符串,然后使用.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;
}
答案 0 :(得分:3)
谢谢大家。所以,根据几个人的建议,我已经完成了以下工作,因为我可以控制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);
我在这里应该做些什么,或者这大部分是否清楚了以前如何通过这个问题? write_ppm的所有其他char参数是否也应该是const?这是一个非常短的函数,它似乎不会修改任何参数。感谢。
答案 1 :(得分:2)
这看起来像是一个没有编写const-correct代码并且具有连锁效应的典型案例。你有几个选择:
如果write_ppm在您的控制之下,或您所知道的任何人的控制权,请让他们使其成为常规
如果不是,您可以保证它永远不会更改文件名,那么const_cast
如果您无法保证,请将您的字符串复制到std :: vector加上null终止符并传递&amp; vec [0](其中vec代表矢量变量的名称)
答案 2 :(得分:1)
您应该使用PPM_file_name.str().c_str()
,因为data()
无法保证返回以null结尾的字符串。
write_ppm()
要么const char*
取第一个参数(承诺不改变字符串的内容),要么不要传递字符串流(因为你不能改变它的内容) )。
你不应该在C ++中使用C风格的强制转换,因为它们不区分不同的强制转换原因。你们正在抛弃const
,如果有的话,应该使用const_cast<>
。但根据经验,const_cast<>
通常只需要使代码编译不是const
- 正确,我认为这是错误的。
答案 3 :(得分:1)
只要write_ppm实际上不改变参数,它绝对安全且便携,在这种情况下,它是未定义的行为。我建议使用const_cast<char*>
而不是C风格的演员。另请考虑使用c_str()
成员而不是data()
成员。前者保证返回以null结尾的字符串
答案 4 :(得分:0)
使用c_str()
代替data()
(c_str()
返回NULL
- 已终止的字符序列。)
答案 5 :(得分:0)
为什么不简单地使用const_cast<char *>(PPM_file_name.str().c_str())
?