2010-11-11 22 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