質問

I have to read a line like this:

0.000000 0.000000 -1.000000 -1.000000 0.230392 0.562016 -1.000000 -1.000000

Using strtok() and a while loop, I'm trying to extract each float numer and store it on my program. There is a problem when converting the token to a floating point number. This is my code:

double p;
char* token = strtok(line, " ");
while (token) {
    p = atof(token);
    printf("atof('%s') = %f\n", token, p);
    token = strtok(NULL, " ");
}

It outputs:

atof('0.000000') = 0,000000
atof('0.000000') = 0,000000
atof('-1.000000') = -1,000000
atof('-1.000000') = -1,000000
atof('0.230392') = 0,000000 <<<---- ???????????
atof('0.562016') = 0,000000 <<<---- ???????????
atof('-1.000000') = -1,000000
atof('-1.000000') = -1,000000

See the problem? Why does atof return 0 when passing a string number between 0 and 1?

役に立ちましたか?

解決

atof() (more specifcally, strtod()) is locale-dependant. Your locale uses , to signify a decimal, while the input string uses . to specify a decimal point. Since atof() stops parsing at the first non-valid character, it returns 0.

The simple fix is to change either your computer's locale to a different locale, or change the input strings.

EDIT: You could update the input string like this:

void update_string(char *str) {
    char *p = str;
    while(*p != '\0') {
        if(*p == '.')
            *p = ',';
        p++;
    }

This is a fairly temporary (and ugly) solution. The prefered solution is to change your locale. You could do it permanently (consult your distro's documentation) or temporarily.

To do it temporarily by just putting LC_NUMERIC="C" in front of the command. So if your compiled program is called a.out, you would execute it using:

LC_NUMERIC="C" ./a.out

or by using setlocale() in your main() function.

他のヒント

The decimal point for atof is locale dependent. In your locale the decimal point seems to be , causing the the parsing to end at the ..

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top