2010-11-11 73 views
3

我写PPM文件(图片格式)到磁盘的功能。它将文件名作为char *数组。在我的主要功能中,我使用stringstream和运算符将一个文件名放在一起。然后,我想将这个结果传递给我的ppm函数。我已经在其他地方看到过这种情况,通常看起来非常复杂的方法(许多转换步骤之间)。传递内容的功能采取的char *作为参数

我所做显示在下面的代码,而棘手的部分,其他人通常做的许多步骤与临时变量是(char*) (PPM_file_name.str().data())。这样做的目的是从stringstream 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; 
} 
+0

你真的改变了write_ppm的文件名吗? – 2010-11-11 16:43:48

+2

我建议在这里使用'const_cast '而不是'(char *)',只是为了清楚你的意图。 – 2010-11-11 16:48:13

+1

如果你正在处理字符串,你应该使用c_str()而不是data()来访问std :: string对象。 c_str()附加一个空字符,data()不附加。 – badgerr 2010-11-11 16:53:49

回答

2

这个貌似某人不写常量,正确的代码和具有连锁效应是一个典型的案例。您有几种选择:

  • 如果write_ppm是你的控制之下,或任何人的,你知道的控制,让他们使它常量CORRCT

  • 如果不是的话,你能保证它永远不会改变文件名,然后const_cast会

  • 如果你不能保证,复制你的字符串转换成一个std :: vector的加空终止,并通过& VEC [0](其中VEC代表你的矢量变量的名称)

0

使用c_str()而不是data()c_str()返回字符的NULL封端的序列)。

1
  1. 你应该使用PPM_file_name.str().c_str(),因为data()不能保证返回一个空终止字符串。

  2. 无论write_ppm()const char*采取的第一个参数(保证不会修改字符串的内容),或者你不能传递一个字符串流(因为你不能改变其内容的方式)。

你不应该使用C-风格转换在C++中,因为他们没有不同的原因,投区分。你们正在铸造const,如果有的话,应该使用const_cast<>来完成。但作为一个经验法则,const_cast<>通常只需要进行代码编译,是不是const -correct,我会考虑一个错误。

1

这是绝对安全和便携只要write_ppm实际上并没有改变说法,在这种情况下,它是不确定的行为。我会建议使用const_cast<char*>而不是C风格的演员。还请考虑使用c_str()成员,而不是data()成员。前者保证返回一个空终止字符串

0

为什么不干脆用const_cast<char *>(PPM_file_name.str().c_str())

+0

该函数采用'char *',而不是'const char *'。我会说API的设计缺陷。 – 2010-11-11 17:12:12

+0

然后用constant_cast跟上它。它应该比.data()的C风格更安全。 – Marcin 2010-11-11 17:17:24

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也是const?这是一个非常短的函数,它似乎不修改任何参数。谢谢。

+0

这是解决问题的惯用方法 - 如果函数采用不会被修改的字符串,则将其声明为const char *。然后它会交替地接受一个字符串文字或一个'c_str()'。 – 2010-11-15 06:17:37