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

How to separate char?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
matsuo



Joined: 17 Feb 2012
Posts: 11

View user's profile Send private message

How to separate char?
PostPosted: Sun Apr 15, 2012 9:41 am     Reply with quote

Hi
I have a problem about separate (split) word from rs232
Sample.
Getc=1/100-------> rs232
I need separate from ("/") and get
A=1
B=100
But how?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Apr 15, 2012 11:58 am     Reply with quote

CCS sample program EX_STR shows you separate words.

Then you convert from ASCII to whatever.

Mike
matsuo



Joined: 17 Feb 2012
Posts: 11

View user's profile Send private message

PostPosted: Sun Apr 15, 2012 7:16 pm     Reply with quote

thanks you for advice...but how to used?
Very Happy
ckielstra



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

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 12:36 am     Reply with quote

I think the code in EX_STR is difficult to understand and does not provide the functionality asked for here.

You could write your own input parser. Use strchr() to search for the '/' character, then use atoi() to convert the data before the '/' and again for the data after the '/' character.

Another option would be to use the sscanf function but this is not included with the CCS compiler. Here is a link to an implementation in the Code Library. But if this is a school assignment I wouldn't recommend to copy that code, it would be too obvious it is a code copy. Good for reference though.
matsuo



Joined: 17 Feb 2012
Posts: 11

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 8:36 am     Reply with quote

Mike Walne wrote:
CCS sample program EX_STR shows you separate words.

Then you convert from ASCII to whatever.

Mike

This is output
Code:
10/200


STATISTICS:

You entered 1 word(s).

You entered 1 unique word(s).

You entered 5 number(s).


Enter a string of text.  The maximum number of characters is 50.


It show number only but how to modify
darkrush



Joined: 29 Sep 2011
Posts: 18
Location: Colombia

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 9:57 am     Reply with quote

you can use this function if the length is always the same.

Code:
char *strndup(char *str, size_t len)
{
   register size_t n;
   register char *dst;

   n = strlen(str);
   if (len < n)
               n = len;
   dst = (char *) malloc(n+1);
   if (dst) {
           memcpy(dst, str, n);
      dst[n] = '\0';
   }
   return dst;
}



It would be something like this for 10/200:

Code:

char *c1, *c2;

c1 = strndup(data_rs232,2);//10
c2 = strndup(data_rs232+3,3);//200

free(c1); //free allocated memory
free(c2);



If you can manipulate the data you receive try sending it with a fixed length and it's done.
ckielstra



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

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 10:33 am     Reply with quote

Aaarrgghh. Please don't use malloc on a small embedded PIC processor!

I know the compiler does support this language feature, but with malloc you run the risk of memory fragmentation. You definitely don't want that to happen. Much better to declare a large buffer on the stack which is guaranteed to be released when you exit your processing function.
darkrush



Joined: 29 Sep 2011
Posts: 18
Location: Colombia

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 11:06 am     Reply with quote

ckielstra wrote:
with malloc you run the risk of memory fragmentation


Yeah, I agree with that, it happened to me, that's why you can see the "free()" after you use the function.

Xavier
jeremiah



Joined: 20 Jul 2010
Posts: 1353

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 12:23 pm     Reply with quote

darkrush wrote:

Yeah, I agree with that, it happened to me, that's why you can see the "free()" after you use the function.


That doesn't get rid of memory fragmentation issue. See:
http://en.wikipedia.org/wiki/Fragmentation_%28computing%29
darkrush



Joined: 29 Sep 2011
Posts: 18
Location: Colombia

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 2:10 pm     Reply with quote

I know is off topic, but the is there any modification to the function to make it more efficient for an embedded device?

I ran many simulations before and the memory is always freed an reused without problem, I think the problem is the malloc implementation.

Xavier
jeremiah



Joined: 20 Jul 2010
Posts: 1353

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 2:29 pm     Reply with quote

the most efficient way in a PIC is to use statically allocated arrays. So for example, instead of:
Code:

char *strndup(char *str, size_t len) ;


do:
Code:

void strndup(char *src, char*dest, size_t len) ;


Mind you, I didn't look at your algorithm at all, but the gist is that rather than output a pointer, pass in the destination pointer, so that way you can statically allocate arrays and just pass them in.
matsuo



Joined: 17 Feb 2012
Posts: 11

View user's profile Send private message

PostPosted: Mon Apr 16, 2012 11:34 pm     Reply with quote

darkrush wrote:
you can use this function if the length is always the same.

Code:
char *strndup(char *str, size_t len)
{
   register size_t n;
   register char *dst;

   n = strlen(str);
   if (len < n)
               n = len;
   dst = (char *) malloc(n+1);
   if (dst) {
           memcpy(dst, str, n);
      dst[n] = '\0';
   }
   return dst;
}



It would be something like this for 10/200:

Code:

char *c1, *c2;

c1 = strndup(data_rs232,2);//10
c2 = strndup(data_rs232+3,3);//200

free(c1); //free allocated memory
free(c2);



If you can manipulate the data you receive try sending it with a fixed length and it's done.


it's error at "malloc" , how to fix it.
ckielstra



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

View user's profile Send private message

PostPosted: Tue Apr 17, 2012 2:16 am     Reply with quote

matsuo wrote:
it's error at "malloc" , how to fix it.
This is what I was afraid of...
You ignore the whole discussion as to why it is better not to use malloc. You were given a routine that seems to do what you want and without understanding what it does you copy/paste it and then run into problems.

Your original question is not so difficult to solve. See my earlier post where I pointed you to the functions strchr() to search the string and atoi() to convert a string to integer. Using these functions it should be only a couple of lines and no need for malloc().

Try to make a function yourself. When you get stuck then post whatever code you have and we will guide you.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Apr 17, 2012 2:20 am     Reply with quote

I wasn't suggesting that EX_STR provided the code to solve your problem, nor that it was easy.

Most of the functions you need are used in that example.

Ckielstra has outlined the basics of what you need to do.

What I'm suggesting is that you cut some code for yourself, then come back when you run into problems.

Assuming that your input from the RS232 is always of the form xxxxx/yyyyy where x and y are variable numbers of digits.
Also that it's in a character array original[] properly terminated with a zero.
If you want something that's simpler to follow, you could:-

(1) Clear two arrays numertor[], denominator[]; and set two indicees i & j to zero.
(2) Compare original[i] with '/'.
(3) If FALSE then copy original[i] to numerator[i]; i++; loop back to (2)
(4) If TRUE then i++; proceed to (5)
(5) Compare original[i] with zero terminator.
(6) If FALSE then copy original[i] to denominator[j]; i++; j++; loop back to (5).
(7) If TRUE proceed to (8).
(8) Convert numerator[] & denominator[] arrays from ASCII to your chosen number format.
(9) Job done.

Mike
matsuo



Joined: 17 Feb 2012
Posts: 11

View user's profile Send private message

PostPosted: Tue Apr 17, 2012 3:01 am     Reply with quote

I try this but it not work
Code:
#define BUFFER_SIZE 5
char array[BUFFER_SIZE];
char first[];
char second[];
int8 start=0;
int j=0;
int i=0;


#INT_RDA
void receive()
{
   array[i]=getc();
   if ((array[i]=='/')||j>0)
   {
   
      strcpy(second,array+i); 
      j++;
      i++;

   }
   else if (!(array[i]=='/')&&j==0)
   {
      strcpy(first,array); 
      i++;
   }
   else
   {
   
   }
   if (i>=BUFFER_SIZE)
   {
      i= 0;
      j= 0;
      start=1;
   }
}
void main()
{
 
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   while(TRUE){   
      if (start){
 
                   printf(first);
                   printf(second);
                    start = 0;
      }
   }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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