1

我的解析函数遇到了一些问题,所以我放了一些 cout 语句来告诉我运行时某些变量的值,我相信 atoi 错误地转换了字符。

这是我的代码的一小段,它的行为很奇怪:

c = data_file.get();
if (data_index == 50)
    cout << "50 digit 0 = '" << c << "' number = " << atoi(&c) << endl;

此语句的输出是: 50 digit 0 = '5' number = 52

我在循环中调用此代码,奇怪的是它正确转换了前 47 个字符,然后在第 48 个字符上它在整数后添加一个 0,在第 49 个字符上它添加一个 1,在第 50 个(见这里)它添加了一个 2,一直到第 57 个字符,它添加了一个 9,然后它继续正确转换到第 239 个字符。

这是奇怪还是什么?

只是为了澄清一点,我将发布整个功能。这个函数得到一个指向空双精度数组(ping_data)的指针:

int parse_ping_data(double* ping_data)
{
    ifstream data_file(DATA_FILE);

    int pulled_digits [4];
    int add_data;
    int loop_count;
    int data_index = 0;

    for (char c = data_file.get(); !data_file.eof(); c = data_file.get())
    {
        if (c == 't' && data_file.get() == 'i' && data_file.get() == 'm' && data_file.get() == 'e' && data_file.get() == '=')
        {
            loop_count = 0;
            c = data_file.get();
            if (data_index == 50)
                    cout << "50 digit 0 = '" << c << "' number = " << atoi(&c) << endl;
            pulled_digits[loop_count] = atoi(&c);

            while ((c = data_file.get()) != 'm')
            {
                loop_count++;
                if (data_index == 50)
                    cout << "50 digit " << loop_count << " = '" << c << "' number = " << atoi(&c) << endl;
                pulled_digits[loop_count] = atoi(&c);
            }
            add_data = 0;
            for (int i = 0; i <= loop_count; i++)
                add_data += pulled_digits[loop_count - i] * (int)pow(10.0,i);

            if (data_index == 50)
                cout << "50 index = " << add_data << endl;
            ping_data[data_index] = add_data;
            data_index++;

            if (data_index >= MAX_PING_DATA)
            {
                cout << "Error parsing data. Exceeded maximum allocated memory for ping data." << endl;
                return MAX_PING_DATA;
            }   
        }
    }

    data_file.close();

    return data_index;
}
4

3 回答 3

7

atoi接受一个字符串,即一个以空结尾的chars 数组,而不是指向单个的指针,char因此这是不正确的,并且会给您带来不可预知的结果。

char c;
//...
/* ... */ atoi(&c) /* ... */

此外,atoi不提供任何检测错误的方法,因此更喜欢strtol和类似的功能。

例如

char *endptr;
char c[2] = {0}; // initalize c to all zero

c[0] = data.file.get(); // c[1] is the null terminator

long l = strtol(c, &endptr, 10);

if (endptr == c)
    // an error occured
于 2009-11-27T20:16:50.060 回答
3

atoi需要一个以 null 结尾的字符串作为输入。您提供的不是以空字符结尾的字符串。

话虽如此,始终值得补充的是,atoi正确使用非常困难(如果可能的话)。atoi是一个不提供错误控制和溢出控制的函数。在 C 标准库中执行字符串表示到数字的转换的唯一正确方法是strto...组中的函数。

实际上,如果您只需要转换单个字符数字,则使用atoi或任何其他字符串转换函数都是一种奇怪的过度杀伤力。正如已经建议的那样,您只需0从字符数字值中减去 的值即可获得相应的数值。语言规范保证这是一个可移植的解决方案。

于 2009-11-27T20:30:55.970 回答
2

没关系,只是我需要将字符转换为以 \0 结尾的字符串。我将其更改为以下代码:

字符缓冲区 [2];

缓冲区[1] = '\0';

缓冲区[0] = data_file.get();

如果(数据索引 == 50)

cout << "50 digit 0 = '" << buffer[0] << "' number = " << atoi(buffer) << endl;

它奏效了。

于 2009-11-27T20:21:10.203 回答