C Преобразование строки в целые числа

Я пытаюсь проанализировать некоторый ввод во встроенной системе. Я ожидаю что-то вроде этого:

SET VARNAME=1,2,3,4,5,6,7,8,9,10\0

Когда я преобразовываю отдельные строки в целые числа, кажется, что и atoi(), и strtol() возвращают 0, если строка начинается с 8.

Вот мой код:

char *pch, *name, *vars;
signed long value[256];
int i;

#ifdef UARTDEBUG
    char convert[100];
#endif
if(strncmp(inBuffer, "SET",3)==0)
{
    pch = strtok(inBuffer," ");
    pch = strtok(NULL," ");
    name = strtok(pch, "=");
    vars = strtok(NULL,"=");

    pch = strtok(vars,",");

    i = 0;
    while(pch != NULL)
    {
        value[i] = atoi(pch);
        #ifdef UARTDEBUG
            snprintf(convert, sizeof(convert), "Long:%d=String:\0", value[i]);
            strncat(convert, pch, 10);
            SendLine(convert);
        #endif
        i++;
        pch = strtok(NULL,",");

        // Check for overflow
        if(i > sizeof(value)-1)
        {
            return;
        }
    }    

    SetVariable(name, value, i);
}

Прохождение:

SET VAR=1,2,3,4,5,6,7,8,9,10\0

дает следующее в моей отладке uart:

Long:1=String:1                                                                
Long:2=String:2                                                                
Long:3=String:3                                                                
Long:4=String:4                                                                
Long:5=String:5                                                                
Long:6=String:6                                                                
Long:7=String:7                                                                
Long:0=String:8                                                                
Long:9=String:9                                                                
Long:10=String:10

ОБНОВЛЕНИЕ:

Я проверил inBuffer как до, так и после 'value[i] = atoi(pch);' и это идентично и, кажется, было разделено до нужной точки.

S  E  T     V  A  R     1     2     3     4     5     6     7     8     9  ,  1  0
53 45 54 00 56 41 52 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00 39 2c 31 30 00 00 00 00 

ОБНОВЛЕНИЕ 2:

Мой раздел UARTDEBUG в настоящее время гласит:

        #ifdef UARTDEBUG
            snprintf(convert, 20, "Long:%ld=String:%s", value[i], pch);
            SendLine(convert);
        #endif

Если я закомментирую строку snprintf(), все работает отлично. Так что же происходит с этим?


person Tim    schedule 30.07.2009    source источник
comment
Что такое объявление для значения []?   -  person bstpierre    schedule 30.07.2009
comment
Возможно, удастся найти ошибку, если вы покажете нам всю функцию (или, по крайней мере, объявления для всех затронутых переменных).   -  person ahy1    schedule 30.07.2009
comment
Вероятно, это не вызывает проблемы, с которой вы сталкиваетесь, но atol() может быть лучшим выбором для вас, поскольку вы объявили его как длинное значение со знаком [256]   -  person Jonas Elfström    schedule 30.07.2009
comment
Что с форматированием? Просто сделайте snprintf(convert, sizeof(convert), "Long:%ld=String:%s", value[i], pch);. Обратите особое внимание на %ld.   -  person Nietzche-jou    schedule 30.07.2009


Ответы (4)


ты не можешь попробовать написать свой собственный atoi? это похоже на десять строк, а затем вы можете легко отладить его (и проверить, где действительно проблема)

  • '0' = 0x30
  • '1' = 0x31

и так далее, вам просто нужно сделать что-то вроде

string[x] - 0x30 * pow(10, n)

для каждой цифры у вас есть

person fnurglewitz    schedule 30.07.2009

Не связано, а

if(i > sizeof(value)-1)
                {
                        return;
                }

должно быть

if(i == sizeof(value)/sizeof(value[0]) )
                {
                        return;
                }

Может быть причиной проблемы, если другие фрагменты кода неправильно выполняют проверку переполнения и из-за этого перезаписывают часть вашей строки.

person Paolo Brandoli    schedule 30.07.2009
comment
Строка, похоже, осталась нетронутой, я предполагаю, что локальные переменные atoi повреждаются. - person Tim; 30.07.2009

Я только что попытался скомпилировать и запустить ваш пример кода в своей собственной системе. Вывод правильный (т.е. «8» появляется там, где он должен быть в выходной строке), что указывает мне на то, что происходит что-то еще, выходящее за рамки кода, который вы нам предоставили.

Я собираюсь пойти на риск и сказать, что одна из ваших переменных или функций попирает вашу входную строку или какую-то другую переменную или массив. SendLine и SetVariable — места для поиска.

Но что более важно, вы не предоставили нам инструменты, которые помогли бы вам решить вашу проблему. Когда вы просите людей помочь вам в отладке вашей программы, предоставьте простой тестовый пример с полным исходным кодом, иллюстрирующий проблему. В противном случае нам остается только догадываться, в чем проблема, что расстраивает нас и непродуктивно для вас.

person Community    schedule 02.08.2009
comment
Я решил проблему, и оказалось, что некоторые локальные переменные snprintf переполняются в локальные переменные atoi. По какой-то причине snprintf вызывает целый ряд проблем в этой встроенной системе. Основная проблема с публикацией тестовых примеров заключается в том, что если вы не тестируете с одним и тем же компилятором, библиотеками и встроенным процессором, скорее всего, мы не будем отлаживать одно и то же. Я разместил примерную строку и то, что я ожидал, и задался вопросом, было ли что-то явно не так. - person Tim; 11.08.2009

atoi возвращает 0 для чего-то, что не может быть представлено как числовое — это всего лишь догадка, но пробовали ли вы сбросить двоичное представление строки (или хотя бы проверить совпадение длин строк)?

person Steve Gilham    schedule 30.07.2009
comment
Это мой следующий шаг после обеда! - person Tim; 30.07.2009