我是否错误地使用了atoi?

发布于 2024-08-12 22:40:06 字数 2249 浏览 11 评论 0原文

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

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

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

此语句的输出是: 50 digital 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;
}

I was having some trouble with my parsing function so I put some cout statements to tell me the value of certain variables during runtime, and I believe that atoi is incorrectly converting characters.

heres a short snippet of my code thats acting strangely:

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

the output for this statement is:
50 digit 0 = '5' number = 52

I'm calling this code within a loop, and whats strange is that it correctly converts the first 47 characters, then on the 48th character it adds a 0 after the integer, on the 49th character it adds a 1, on the 50th (Seen here) it adds a two, all the way up to the 57th character where it adds a 9, then it continues to convert correctly all the way down to the 239th character.

Is this strange or what?

Just to clarify a little more i'll post the whole function. This function gets passed a pointer to an empty double array (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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

歌枕肩 2024-08-19 22:40:06

atoi 接受一个字符串,即一个以 null 结尾的 char 数组,而不是指向单个 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

atoi takes a string, i.e. a null terminated array of chars, not a pointer to a single char so this is incorrect and will get you unpredictable results.

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

Also, atoi doesn't provide any way to detect errors, so prefer strtol and similar functions.

E.g.

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
满意归宿 2024-08-19 22:40:06

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

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

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

atoi expects a null-terminated string as an input. What you are supplying is not a null-terminated string.

Having said that, it is always worth adding that it is very difficult (if at all possible) to use atoi properly. atoi is a function that offers no error control and no overflow control. The only proper way to perform string-representation-to-number conversion in C standard library is functions from strto... group.

Actually, if you need to convert just a single character digit, using atoi or any other string conversion function is a weird overkill. As it has already been suggested, all you need is to subtract the value of 0 from your character digit value to get the corresponding numerical value. The language specification guarantees that this is a portable solution.

冰魂雪魄 2024-08-19 22:40:06

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

char buffer [2];

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

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

if (data_index == 50)

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

并且它起作用了。

Nevermind, it was simply that I needed to convert the character into a string terminated by \0. I changed it to this code:

char buffer [2];

buffer[1] = '\0';

buffer[0] = data_file.get();

if (data_index == 50)

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

and it worked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文