2016-11-28 114 views
0

我想編寫一個將float轉換爲const char *的C++函數。在這個函數中,傳遞一個參數來指定輸出值應該表示的小數位數。我已經提出了這個功能,它很好地工作。在小數點後的浮點數中設置數字

我想問一下,有沒有更好的方法寫這個函數?

static const char* getString(float value, int decimalPlaces) 
{ 
    char strValue[sizeof value]; 
    sprintf(strValue, "%.%df", value, decimalPlaces); 
    return strValue; 
} 
+0

'sizeof value'是用來表示'float'的字節數,對於'sprintf'來說可能不夠。您返回一個指向本地數組的指針,該數組的生存期在您可以使用之前結束。 – aschepler

回答

6

沒有與你的函數的兩個主要問題。

要開始的大小float是在大多數平臺上的四個字節,這意味着你的數組只有四個元素。對於浮點值的所有數字都不夠。寫出界限將導致未定義的行爲

第二個問題是你返回一個指向局部變量的指針。一旦函數返回,數組strValue將超出範圍,並且指針現在將成爲所謂的雜散指針。解除引用也會導致未定義的行爲。

總之,你的功能確實是而不是「很好地工作」。它根本不起作用。

顯而易見的解決方案是使用std::stringstd::to_string將浮點值轉換爲字符串。然後,當你需要一個C風格的以null結尾的字符串(無論出於何種原因)時,你可以使用字符串c_str()獲得這樣一個指針。

如果您需要特定的小數位數,請使用std::ostringstream和標準I/O manipulators以您想要的方式格式化字符串。如果你的目標是獲得一個字符串輸出,你當然可以跳過這一步,並在編寫輸出時直接使用操縱器。

+0

非常感謝你的答案。這裏我想要的是返回一個const char *。使用c_str(),我們可以實現它。所以,如果我們使用這種方法,你不認爲有不必要的步驟,如先轉換爲std :: string,然後轉換爲const char *。 –

2

當你return strValue;你會返回一個指向一個局部變量。這意味着當函數結束變量消失,現在你有一個什麼都沒有的指針。使用該指針是未定義的行爲。

你要麼不得不使用new[]分配緩衝區,然後你需要記住delete[]指針在呼叫站點或使用類似std::string的東西,並讓字符串本身處理內存管理。

個人而言,我會用一個std::stringstd::stringstream,如:

static std::string getMString(float value, int decimalPlaces) 
{ 
    std::stringstream stream; 
    stream << std::fixed << std::setprecision(decimalPlaces) << value; 
    return stream.str(); 
} 
+0

非常感謝你的回答。這裏我想要的是返回一個const char *。使用c_str(),我們可以實現它。所以,如果我們使用這種方法,你不認爲有不必要的步驟,如先轉換爲std :: string,然後轉換爲const char *。 –

+1

@TharinduKumara如果你想返回一個指針,你需要'new []'和'delete []'。就我個人而言,我會返回字符串,然後如果您需要'const char *',那麼您可以在調用站點中返回字符串的'c_str()'方法。 – NathanOliver

2

沒有您的功能的問題,因爲char strValue[]被刪除,一旦你離開getMString並返回指向被刪除的數據,這是UB。

我建議不創造任何東西,而是用C++ 11 std::to_string(float)

+0

該數組不是**刪除**(沒有調用「刪除」)。它只是消失。 –

+0

這就是爲什麼他們說地方對象的生命結束。它是實現定義的,什麼以及什麼時候該內存中的數據會發生什麼 – Swift