字符串浮動轉換?
回答
scanf
,operator>>
istreams,而strtof
將是明顯的選擇。
有是也atof
,但是,像atoi
,它沒有辦法告訴你有輸入錯誤,所以一般情況下最好是避免兩者。
「strtof」的+1。 – 2010-09-29 20:34:28
的ATOF()函數會很有幫助。 http://www.cplusplus.com/reference/clibrary/cstdlib/atof/
我強烈建議''strtod()'over atof()',因爲當你用'strtod()'得到意外的輸入時,你有更好的機會發現出了什麼問題。 – RBerteig 2010-09-29 23:36:44
這是完全正確的。我同意。 – 2010-09-30 13:19:47
爲C
strtod()
和C99
朋友strtof()
和strtold()
(在相同的鏈接說明)已經有一個算法來實現。
如果您在編寫自己的過程中遇到問題,請發佈您的代碼和關於它的特定問題。
'strtof'而不是'strtod',因爲提問者想要一個'float'而不是'double'。 – 2010-09-29 20:35:34
右斯蒂芬,謝謝(但strtof和strtold是「新」)。發佈編輯。 – pmg 2010-09-29 20:41:06
使用'strtod'並將結果轉換爲'float'(隱式或轉換)與strtof'一樣好,並且更便於移植。 – 2010-09-29 21:00:02
您可以使用升壓:lexical_cast的
http://www.boost.org/doc/libs/1_44_0/libs/conversion/lexical_cast.htm
對於C++,你可以使用boost::lexical_cast:
std::string str("4.72");
float x = boost::lexical_cast<float>(str);
對於C,你可以使用的sscanf:
char str[]= "4.72";
float x;
sscanf(str, "%f", &x);
對於C++這是我使用的算法:
bool FromString(const string& str, double& number) {
std::istringstream i(str);
if (!(i >> number)) {
// Number conversion failed
return false;
}
return true;
}
我在過去使用atof()進行轉換,但是我發現這個問題很嚴重,因爲如果沒有有效的轉換,它會返回(0.0)。所以,你不知道它是否失敗並返回零,或者如果字符串實際上有「0」。
從cplusplus.com:「stringstream
提供了一個操作字符串的接口,就好像它們是輸入/輸出流一樣。」
可以初始化你的字符串stringstream
然後閱讀使用operator>>
從stringstream
的浮動,就像你會與cin
。
下面是一個例子:
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main() {
string s = "4.72";
stringstream sstrm(s);
float x;
sstrm >> x;
cout << x << endl;
}
我假設你想要一個實際的算法,而不是庫函數已經這樣做了。我沒有時間來編寫和測試實際的代碼,但這裏是我會做什麼:
- 初始化將被用作累加器0
- 想出一個浮在小數位在字符串中,這會讓你知道每個數字的「列」是什麼(即100s,10s,1s,1/10s等)。
- 從字符串的開頭開始。
- 取這個數字,轉換爲一個int(通過從ASCII值中減去0x30來完成)
- 乘以place列的值(對於示例中的第一個數字,即4 * 1 == 4 ,下一個數字7 * 0.1 == 0.7)。
- 將結果添加到累加器中
- 對每個剩餘數字從第4步開始重複。
- 累加器現在包含您的結果。
由於在此循環的每次迭代中基數10和基數2之間的轉換舍入,因此您從該算法得到的結果可能不是最接近原始值的二進制表示。雖然......我可能不知道改進它的好方法,但也許別人可以用這種方法加以改進。
不要忘記處理像'-1.2e-3'這樣的數字。這種轉換充滿了微妙和邊緣情況。絕不容易得到正確的答案。如果你必須自己實現它,在每個你可以想象的邊緣情況下測試它的廢話。然後擔心。不要忘記NaN和INF案例。 – RBerteig 2010-09-29 20:53:57
@Rerteig:如果這是我的字符串轉換函數,我可以簡單地聲明負數和科學記數法是無效的;)但是的確,是的,它需要比我寫的更復雜。我想OP只是試圖包裝是圍繞如何轉換是可能的。 – rmeador 2010-09-29 22:15:26
當然,您可以決定爲了簡化問題而應該處理的內容的合理範圍。我只是想添加提醒,即將文本轉換爲浮點可能需要處理比「4.72」更復雜的情況。例如,我見過的符合C89的'strtod()'的一個實現是大約80行密集且幾乎不被評論的代碼。 – RBerteig 2010-09-29 23:27:04
按照您的要求爲算法,而不是一個方法,這裏是我的一個簡單的算法解釋(和C中的實現):對於點前值
- 初始化4整型變量,一個,一個用於後面的部分,一個用於尾數的功能,另一個用於標誌。比方說,f,m,d,sign = 1.
- 先看+或 - 號開頭。如果沒有符號字符或+符號,則繼續。如果第一個字符是 - ,那麼sign = -1。
- 然後,讀取一個整數值爲f,直到a。或NULL字符。
- 如果最後出現一個點字符,則開始將尾數部分與上一步一樣讀入m。但這一次也乘以每個數字乘以10。
- 最後,返回符號*(f +(float)m/d)。該投射確保劃分在浮點上完成,並且表達式的類型爲浮點型。
我想,閱讀代碼可能會更容易。所以這裏是代碼:
float atof(char *s)
{
int f, m, sign, d=1;
f = m = 0;
sign = (s[0] == '-') ? -1 : 1;
if (s[0] == '-' || s[0] == '+') s++;
for (; *s != '.' && *s; s++) {
f = (*s-'0') + f*10;
}
if (*s == '.')
for (++s; *s; s++) {
m = (*s-'0') + m*10;
d *= 10;
}
return sign*(f + (float)m/d);
}
簡單的部分來源的好和清晰的解釋。不要忘記處理'-1e-6','.3e + 5','+ 2.e-4'等等,或者明確指出你不允許這種形式。考慮更好地處理格式錯誤的數字(嘗試使用「ABC」作爲輸入)。另請考慮處理NaN和INF。 C99要求'scanf()'能夠正確地恢復由'printf()'打印的值,甚至包括NaN和INF。 C89沒有,但是它的'strtod()'確實處理了'E'表示法。 – RBerteig 2010-09-29 23:33:40
- 1. 字符串轉換爲浮動動態
- 2. 轉換帶符號的字符串以浮動並浮動回字符串
- 3. 字符串浮動vs雙重轉換
- 4. 轉換「字符串」爲「浮動」?
- 5. 不能字符串轉換爲浮動
- 6. c#字符串浮動轉換無效?
- 7. 將字符串轉換爲浮動logstash
- 8. 迅速字符串轉換爲浮動
- 9. Python字符串浮動轉換
- 10. 轉換字符串中的ios浮動
- 11. 將浮動字符串轉換爲字符串
- 12. 的浮動字符串轉換爲浮動
- 13. 轉換字符串浮動沒有沉默NaN/Inf轉換
- 14. 轉換二進制字符串轉換成浮動
- 15. 「替換」將字符串轉換爲浮動。如何保持字符串格式?
- 16. 浮到字符串轉換在C++
- 17. 將字符串轉換爲浮點數
- 18. 將字符串轉換爲浮點數
- 19. 將字符串轉換爲浮點數?
- 20. 將字符串轉換爲浮點Java
- 21. 基本字符串到浮點轉換
- 22. C字符串浮點轉換
- 23. 將字符串轉換爲浮點數
- 24. VBS將字符串轉換爲浮點
- 25. 將字符串轉換爲浮點數
- 26. 從字符串轉換爲浮點數
- 27. 字符串到浮點數轉換
- 28. C#字符串到浮點型轉換
- 29. 大熊貓自動轉換我的字符串列浮動
- 30. 將字符串轉換爲浮動數字Javascript
你真的想要一個*算法*,或者只是一個已經寫好的函數嗎? – fennec 2010-09-29 20:10:33