2013-03-22 69 views
3
using namespace std; 
int main(int argc, char *argv[]) { 
    char c[] = {'0','.','5'}; 
    //char c[] = "0.5"; 
    float f = atof(c); 
    cout << f*10; 
    if(c[3] != '\0') 
    { 
     cout << "YES"; 
    } 
} 

OUTPUT:5YESATOF和非空終止字符數組

ATOF是否與非空終止字符數組過工作?如果是這樣,它如何知道在哪裏停止?

+1

_I無法重現it_ - **我認爲這是一個未定義的行爲**。 – deepmax 2013-03-22 12:21:21

+2

@MM。幸運的是,它只是格式化了我的硬盤。 – 2013-03-22 12:21:46

+0

@MM。這是因爲它是未定義的行爲,很可能c後的內存中有空終止符。 – Overv 2013-03-22 12:22:30

回答

5

atof是否也使用非null終止的字符數組?

不,它不是std::atof需要輸入中以空字符結尾的字符串。未能滿足此前提條件是未定義行爲

未定義行爲意味着任何東西都可能發生,包括程序看起來工作正常。這裏發生的事情是偶然的,你的內存中有一個字節位於數組的最後一個元素之後,這個字節不能被解釋爲浮點數的表示的一部分,這就是爲什麼你的執行std::atof停止。但那是不可靠的。

你應該修改你的程序是這樣的:

char c[] = {'0', '.', '5', '\0'}; 
//       ^^^^ 
+1

有沒有'實際上,數組後面的'\ 0''。注意代碼中的測試(也調用UB)。 'atof'停在任何不能被解釋爲浮點數表示的一部分的字符上。 – jrok 2013-03-22 12:29:17

+0

@jrok:對,讓我編輯。謝謝 – 2013-03-22 12:30:51

+2

@jrok:但是沒有*要求*,它在遇到不屬於浮點數的字符時停止。這只是一個實施問題的質量。一個糟糕的'atof'解釋當然可以在其輸入上調用'strlen',儘管這在某些情況下可能會使速度降低1000倍。 – 2013-03-22 12:35:54

0

從MSDN上(可能適用於其他編譯器)的atof()功能的描述:

功能停止讀取輸入字符串在作爲數字的一部分,它無法識別的第一個字符。該字符可能是終止字符串的空字符('\ 0'或L'\ 0')。

2

不,atof不與非空終止陣列工作:它停止時,它的陣列,你在傳遞結束後發現零傳遞而不終止的數組是不確定的行爲,因爲它會導致功能。讀取數組的末尾。在你的例子中,函數可能訪問了你已經分配給f的字節(雖然在那裏沒有確定性,因爲f不需要在存儲器中跟隨c[])。

char c[] = {'0','.','5'}; 
char d[] = {'6','7','8'}; 
float f = atof(c); // << Undefined behavior!!! 
float g = atof(d); // << Undefined behavior!!! 
cout << f*10; 

上面prints5.678,指出讀取過去陣列的端部已取得的事實。

0

它必須是0終止或文本必須包含不屬於該數字的字符。

1

否... atof()需要以空字符結尾的字符串。

如果你有一個字符串,你需要轉換它不是空的終止,你可以嘗試將它複製到一個目標緩衝區,基於每個字符的值是一個有效的數字。一些東西的影響...

char buff[64] = { 0 }; 

for(int i = 0; i < sizeof(buff)-1; i++) 
{ 
    char input = input_string[i]; 

    if(isdigit(input) || input == '-' || input == '.') 
     buff[i] = input; 
    else 
     break; 
} 

double result = atof(buff); 
+1

[_注意C字符串不暗示使用ASCII ..._](http://en.wikipedia.org/wiki/Null-terminated_string) – deepmax 2013-03-22 12:29:09

+1

確實,ASCIIZ不是一個合適的術語。在C語言中,該術語僅僅是「字符串」,它被定義爲包含空終止的要求。否則,您可以將其解釋爲「C字符串」(即使用C的術語定義的字符串)或「以空字符結尾的字符串」。 – 2013-03-22 12:34:43

+0

我的年齡是否顯示? 〜哈哈〜 – 2013-03-22 12:38:25