views:

333

answers:

5

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?

A: 

what libc do you use?

No idea, I'm using Keil UVision3 and I cant really work out where its including it from.
Tim
A: 

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)?

Steve Gilham
Thats my next step after lunch!
Tim
+1  A: 

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

Paolo Brandoli
The string appears to survive intact, my guess is that atoi local variables are getting corrupted
Tim
+1  A: 

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

tr3
+1  A: 

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.

Ive solved the problem and it appeared that some snprintf local variables were overflowing into the atoi local variables. For some reason snprintf causes a whole world of issues on this embedded system. The main issue with posting test cases is that unless you are testing with the same compiler, libraries and embedded processor, the chances are we are not going to be debugging the same thing. I posted an example string and what im expecing out and wondered if there was anything blatently wrong.
Tim