2013-03-22 68 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