atof和非null终止的字符数组

时间:2013-03-22 12:19:33

标签: c++ c atof

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";
    }
}

输出:5YES

atof是否也适用于非空终止字符数组?如果是这样,它怎么知道在哪里停止?

6 个答案:

答案 0 :(得分:5)

  

atof是否也适用于非空终止字符数组?

不,它没有std::atof在输入中需要以null结尾的字符串。未能满足此前提条件的是未定义行为

未定义的行为意味着任何都可能发生,包括看起来工作正常的程序。这里发生的事情很可能是你的数组的最后一个元素之后的内存中有一个字节,它不能被解释为浮点数表示的一部分,这就是你std::atof的实现停止的原因。但那是不可靠的。

你应该这样修理你的程序:

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

答案 1 :(得分: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;

以上prints 5.678,指出已经在数组末尾读取的事实。

答案 2 :(得分: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 );

答案 3 :(得分:0)

来自MSDN上atof()函数的描述(可能适用于其他编译器):

  

该函数停止读取第一个字符处的输入字符串,该字符串无法识别为数字的一部分。该字符可以是终止字符串的空字符('\ 0'或L'\ 0')。

答案 4 :(得分:0)

必须为0终止或文本必须包含不属于该数字的字符。

答案 5 :(得分:0)

std :: string已经终止了一个带有NULL的字符串!

为什么不呢

std::string number = "7.6";
double temp = ::atof(number.c_str());

您也可以使用stringstream或boost :: lexical_cast

http://www.boost.org/doc/libs/1_53_0/doc/html/boost_lexical_cast.html http://www.cplusplus.com/reference/sstream/stringstream/