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

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(), все работает отлично. Так что с этим происходит?

1
Tim 30 Июл 2009 в 15:15

4 ответа

Лучший ответ

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

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

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

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

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

1
dfa 30 Июл 2009 в 16:09

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

0
Steve Gilham 30 Июл 2009 в 11:55

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

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

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

1
froofroofroofroo 2 Авг 2009 в 06:24

Не связано, но

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

Должно быть

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

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

1
Paolo Brandoli 30 Июл 2009 в 12:11