Я неправильно использую Atoi? - PullRequest
1 голос
/ 27 ноября 2009

У меня были некоторые проблемы с функцией синтаксического анализа, поэтому я добавил несколько операторов 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-е (видно здесь) добавляет два, вплоть до 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;
}

Ответы [ 3 ]

6 голосов
/ 27 ноября 2009

atoi принимает строку, то есть массив с нулевым символом в конце char s, а не указатель на один char, так что это неверно и приведет к непредсказуемым результатам.

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

Кроме того, atoi не предоставляет никакого способа обнаружения ошибок, поэтому предпочитайте strtol и подобные функции.

1011 * Е.Г. *

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
3 голосов
/ 27 ноября 2009

atoi ожидает строку с нулевым символом в конце в качестве входных данных. То, что вы предоставляете, не является строкой с нулевым символом в конце.

Сказав это, всегда стоит добавить, что очень трудно (если вообще возможно) правильно использовать atoi. atoi - это функция, которая не обеспечивает контроль ошибок и контроль переполнения. Единственный правильный способ выполнить преобразование представления строки в число в стандартной библиотеке C - это функции из strto... group.

На самом деле, если вам нужно преобразовать только одну символьную цифру, использование atoi или любой другой функции преобразования строк является странным излишним. Как уже было предложено, все, что вам нужно, это вычесть значение 0 из значения вашего символа, чтобы получить соответствующее числовое значение. Спецификация языка гарантирует, что это переносимое решение.

2 голосов
/ 27 ноября 2009

Не важно, мне просто нужно было преобразовать символ в строку, оканчивающуюся \ 0 Я изменил его на этот код:

буфер символов [2];

буфер [1] = '\ 0';

buffer [0] = data_file.get ();

if (data_index == 50)

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

и это сработало.

...