atof and non-null terminated character array

2019-07-07 14:37发布

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: 5YES

Does atof work with non-null terminated character arrays too? If so, how does it know where to stop?

标签: c++ c atof
6条回答
\"骚年 ilove
2楼-- · 2019-07-07 15:05

Does atof work with non-null terminated character arrays too?

No, it doesn't. std::atof requires a null-terminated string in input. Failing to satisfy this precondition is Undefined Behavior.

Undefined Behavior means that anything could happen, including the program seeming to work fine. What is happening here is that by chance you have a byte in memory right after the last element of your array which cannot be interpreted as part of the representation of a floating-point number, which is why your implementation of std::atof stops. But that's something that cannot be relied upon.

You should fix your program this way:

char c[] = {'0', '.', '5', '\0'};
//                         ^^^^
查看更多
男人必须洒脱
3楼-- · 2019-07-07 15:06

It must either be 0 terminated or the text must contain characters that do not belong to the number.

查看更多
我只想做你的唯一
4楼-- · 2019-07-07 15:17

No... atof() requires a null terminated string.

If you have a string you need to convert that is not null terminated, you could try copying it into a target buffer based on the value of each char being a valid digit. Something to the effect of...

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 );
查看更多
等我变得足够好
5楼-- · 2019-07-07 15:21

std::string already terminate a string with NULL!

So why not

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

You can also do it with the stringstream or 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/

查看更多
叼着烟拽天下
6楼-- · 2019-07-07 15:24

From the description of the atof() function on MSDN (probably applies to other compilers) :

The function stops reading the input string at the first character that it cannot recognize as part of a number. This character may be the null character ('\0' or L'\0') terminating the string.

查看更多
家丑人穷心不美
7楼-- · 2019-07-07 15:26

No, atof does not work with non-null terminated arrays: it stops whenever it discovers zero after the end of the array that you pass in. Passing an array without termination is undefined behavior, because it leads the function to read past the end of the array. In your example, the function has likely accessed bytes that you have allocated to f (although there is no certainty there, because f does not need to follow c[] in memory).

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

The above prints 5.678, pointing out the fact that a read past the end of the array has been made.

查看更多
登录 后发表回答