CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

What's wrong with this parse function?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Huyvu90
Guest







What's wrong with this parse function?
PostPosted: Sat May 06, 2006 5:31 am     Reply with quote

values = "M 1 2 3 4 5 6 7 8 9"

The goal of parsevalues() is to split up the numbers in variable "values" and store them in an int array of 9 elements (parameters[]).

The function parsevalues() does somewhat work but the array doesn't seem to be updating as often. Are there any error in the code that I missed?

Quote:
void parsevalues()
{
int i = 0;
int j = 0;
char singlevalue[3];

char term[3], *ptr;
strcpy(term," ");
ptr = strtok(values, term);

while(ptr!=0) {

strcpy(singlevalue,ptr);

if(i<=9)
{
parameters[i] = atoi(singlevalue);
i++;
}

ptr = strtok(0, term);
}

}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sat May 06, 2006 8:50 am     Reply with quote

The first time through were will ptr point? Then you do a strcpy into singlevalue. You WILL overflow this. singlevalue should be at least the same size as values.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat May 06, 2006 10:37 am     Reply with quote

Mark wrote:
The first time through were will ptr point?
He did initialize pointer, that's allright.


- You are only interested in the numbers? Than add an extra call to strtok() in order to skip the first element in your string.

Quote:
and store them in an int array of 9 elements (parameters[])
Code:
 if(i<=9)
Your counter i starts at 0, so use '<' instead of '<='.


- As Mark already pointed out the strcpy is wrong because of array overflowing. Strcpy continues copying until it reaches the null character at the end of the string while you want it to stop at the space character between the parameters.
Note: The example program for strtok() in the manual has the same error.


Possible solutions are:
1) Write your own copy routine that stops at the space character. This is the best solution.
2) A little bit quicker but less flexible: Use strncpy instead of strcpy. Strncpy will stop the copy at the maximum amount of characters you specify.
3) Or quick-and-dirty, don't copy at all using the knowledge that atoi() will stop at any non-digit character.
Code:
void parsevalues()
{
  int i = 0;
  char term[3], *ptr;

  strcpy(term," ");

  // Extra call to strtok in order to skip first parameter.
  ptr = strtok(values, term);

  ptr = strtok(0, term);
  while (ptr!=0)
  {
    if (i<9)     // Changed '<=' to '<'
    {
      parameters[i] = atoi(ptr);    // atoi will stop at first non-digit character (space or terminating zero).
      i++;
    }

    ptr = strtok(0, term);
  }
}


Edit 1: Moved the note about the error in the CCS example to the correct paragraph.
Edit 2: Fixed a bug in skipping the first parameter (now pass 0 as parameter to strtok).


Last edited by ckielstra on Wed May 10, 2006 2:05 am; edited 2 times in total
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sun May 07, 2006 9:50 am     Reply with quote

ckielstra wrote:
Mark wrote:
The first time through were will ptr point?
He did initialize pointer, that's allright.


I did see that. It was a rhetorical question trying to get the poster to visualize where the pointer was pointer and see how long the string would be. Reading back over my post, I can see how unclear I was.
HUyvu80
Guest







didn't work
PostPosted: Tue May 09, 2006 11:21 pm     Reply with quote

ckielstra wrote:
Mark wrote:
The first time through were will ptr point?
He did initialize pointer, that's allright.


- You are only interested in the numbers? Than add an extra call to strtok() in order to skip the first element in your string.

Quote:
and store them in an int array of 9 elements (parameters[])
Code:
 if(i<=9)
Your counter i starts at 0, so use '<' instead of '<='.


- As Mark already pointed out the strcpy is wrong because of array overflowing. Strcpy continues copying until it reaches the null character at the end of the string while you want it to stop at the space character between the parameters.
Note: The example program for strtok() in the manual has the same error.


Possible solutions are:
1) Write your own copy routine that stops at the space character. This is the best solution.
2) A little bit quicker but less flexible: Use strncpy instead of strcpy. Strncpy will stop the copy at the maximum amount of characters you specify.
3) Or quick-and-dirty, don't copy at all using the knowledge that atoi() will stop at any non-digit character.
Code:
void parsevalues()
{
  int i = 0;
  char term[3], *ptr;

  strcpy(term," ");

  // Extra call to strtok in order to skip first parameter.
  ptr = strtok(values, term);

  ptr = strtok(values, term);
  while (ptr!=0)
  {
    if (i<9)     // Changed '<=' to '<'
    {
      parameters[i] = atoi(ptr);    // atoi will stop at first non-digit character (space or terminating zero).
      i++;
    }

    ptr = strtok(0, term);
  }
}


Edit: Moved the note about the error in the CCS example to the correct paragraph.


The code didn't work. I looked up atoi and it has the following
"Parameters:
string is a pointer to a null terminated string of characters."

atoi does not stop whitespace or 0 like u said but a null character like strcpy.

Is there anyway except writing my own parse function?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed May 10, 2006 2:06 am     Reply with quote

Quote:
The code didn't work. I looked up atoi and it has the following
"Parameters:
string is a pointer to a null terminated string of characters."

atoi does not stop whitespace or 0 like u said but a null character like strcpy.
atoi stops at a null character like strcpy but also at the first whitespace. Check the code for atoi in the file stdlib.h, here you see the following loop:
Code:
         while (c >= '0' && c <= '9')
         {
            result = 10*result + (c - '0');
            c = s[index++];
         }
atoi() will stop parsing at any character out of the range '0' - '9'.


I tested the function above in the MPLAB simulator and CCS version 3.226 and it works great. There was only an error in skipping the first parameter, see my edited code in the program above.

If it doesn't work for you then there must be an error somewhere else in your program. Post a complete compilable program and we will have a look.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group