Question

I'm trying to parse some input on an embedded system. I'm expecting something like this:

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

When I'm converting the separate strings to ints, both atoi() and strtol() seem to be returning 0 if the string begins with 8.

Here is my code:

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);
}

Passing it:

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

gives the following in my uart debug:

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

UPDATE:

I've checked the inBuffer both before and after 'value[i] = atoi(pch);' and it's identical and appears to have been split up to the right point.

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 

UPDATE 2:

My UARTDEBUG section currently reads:

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

If I comment out the snprintf() line, everything works perfectly. So what's going on with that?

Was it helpful?

Solution

can't you try to write your own atoi? it's like ten lines long and then you can debug it easily (and check where the problem really is)

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

and so on, you just need to do something like

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

for each digit you have

OTHER TIPS

Not related, but

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

should be

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

May be the cause of the problem if other pieces of code do the overflow checking in the wrong way and because of that they overwrite part of your string

I've just tried compiling and running your sample code on my own system. The output is correct (i.e. '8' appears where it should be in the output string) which indicates to me that something else is going on outside of the scope of the code you've provided to us.

I'm going to go out on a limb and say that one of your variables or functions is trampling your input string or some other variable or array. SendLine and SetVariable are places to look.

But more importantly, you haven't given us the tools to help you solve your problem. When asking people to help you debug your program, provide a simple test case, with full source, that exemplifies the problem. Otherwise, we're left to guess what the problem is, which is frustrating for us and unproductive for you.

atoi returns 0 for something that it can't render as numeric -- this is just a hunch, but have you tried dumping the binary representation of the string (or even checking that the string lengths match up)?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top