3

我有一个将 ppm 文件(一种图片格式)写入磁盘的功能。它将文件名作为 char* 数组。在我的主函数中,我使用字符串流和 << 运算符组合了一个文件名。然后,我想将结果传递给我的 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;
}
4

6 回答 6

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

于 2010-11-12T17:36:41.697 回答
2

这看起来像是一个典型的案例,即有人没有编写 const 正确的代码并且它具有连锁效应。你有几个选择:

  • 如果 write_ppm 在您的控制之下,或者在您认识的任何人的控制之下,请让他们将其设为 const corrct

  • 如果不是,并且您可以保证它永远不会更改文件名,那么 const_cast

  • 如果不能保证,请将字符串复制到 std::vector 加上空终止符并传递 &vec[0] (其中 vec 表示向量变量的名称)

于 2010-11-11T16:57:30.810 回答
1
  1. 您应该使用PPM_file_name.str().c_str(), 因为data()不能保证返回以空字符结尾的字符串。

  2. 要么write_ppm()应该接受它的第一个参数const char*(承诺不改变字符串的内容),要么你不能传递一个字符串流(因为你不能那样改变它的内容)。

您不应该在 C++ 中使用 C 风格的强制转换,因为它们不区分不同的强制转换原因。你的正在抛弃const,如果有的话,应该使用const_cast<>. 但根据经验,const_cast<>通常只需要编译不const正确的代码,我认为这是一个错误。

于 2010-11-11T16:53:53.363 回答
1

只要 write_ppm 实际上不更改参数,它就绝对安全且可移植,在这种情况下,它是未定义的行为。我建议使用const_cast<char*>而不是 C 风格的演员表。还可以考虑使用c_str()member 而不是data()member。前者保证返回一个以空字符结尾的字符串

于 2010-11-11T16:54:18.330 回答
0

使用c_str()代替data()c_str()返回以NULL- 结尾的字符序列)。

于 2010-11-11T16:53:33.553 回答
0

为什么不简单地使用const_cast<char *>(PPM_file_name.str().c_str())

于 2010-11-11T16:54:22.037 回答