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

Handling strings - the newcomer to CCS c way :)

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



Joined: 16 Sep 2008
Posts: 51

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

Handling strings - the newcomer to CCS c way :)
PostPosted: Sat Jan 10, 2009 6:20 am     Reply with quote

Hello 2 all !

By the following code, i am trying to read a character from serial port, translate this character into binary form and store the result in a string.

Parameters : PIC18f452 @ 10 MHz and using CCS C compiler version 4.057.

The code looks like this :
Code:

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <string.h>

void main()
{
   char c,i,temp[1],buffer[8];
 
while(1)         
    {
c=getc();
for(i = 0; i < 8; i++)
    {
if(c & 0x80)
    {
sprintf(temp,"%c",'1');
    }
else
    {
sprintf(temp,"%c",'0');
    }
strcpy(buffer,temp);
c <<= 1;
    }
printf("%s /n/r",buffer);
    }



So ..... i am getting the character from serial port by using the "getc()" function. Next, i'm doing a bitwise AND (http://en.wikipedia.org/wiki/Bitwise_operation#AND) of the character with the hex number 0x08 (binary representation :10000000). If the current bit is a "1"or a "0", i'm copying the value into a temporary buffer wich is a 1 character long. Then the result of the "IF" statement, is copyed into a larger string, 8 characters wide.

So, for a 0x02, i have to get 00000010.

Instead, i'm getting an endless string of zeroes. Sad

WHERE IS MY MISTAKE ??

Thank you very much for your time !
Andrew83



Joined: 16 Sep 2008
Posts: 51

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

PostPosted: Sat Jan 10, 2009 6:34 am     Reply with quote

Hmmm...i will try to use the "strcat()" function instead of the "strcpy()".

Let's see what happens ! Confused
ckielstra



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

View user's profile Send private message

PostPosted: Sat Jan 10, 2009 6:39 am     Reply with quote

First of all, in C a string is always terminated by a null character. So when declaring your variables you have to add 1 extra character to the desired length.
Change:
Code:
   char c,i,temp[1],buffer[8];
to:
Code:
   char c,i,temp[2],buffer[9];


A second problem is that you copy the temporary string to the output buffer inside the loop and hereby overwrite the existing data. What is missing is a mechanism to 'shift' the destination output 1 character in every loop iteration.
Change:
Code:
strcpy(buffer,temp);
to:
Code:
strcpy(&buffer[i],temp);


Note that the sprintf function is causing some overhead. Your program would be smaller and easier to read when you optimize the sprintf function 'away'. I leave this as an exercise to the poster.
Andrew83



Joined: 16 Sep 2008
Posts: 51

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

PostPosted: Sat Jan 10, 2009 6:42 am     Reply with quote

Thank you very much ckielstra ! Thank you for the quick answer ! Surprised
Andrew83



Joined: 16 Sep 2008
Posts: 51

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

PostPosted: Sat Jan 10, 2009 7:34 am     Reply with quote

So...here is the code without using the "sprintf()" function! Very Happy
ckielstra rules !! Thank you again 4 opening my eyes to the real solution of the problem !

Code:


#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <string.h>

void main()
{
char c,d,i,temp[2],buffer[9];

while(1)

{
     c=getc();
   for(i = 0; i < 8; i++)
{
   if(c & 0x80)
{
   d='1';
}
else
{
   d='0';
}
   c <<= 1;
   strcpy(&buffer[i],&d);
}
printf("%s \n\r",buffer);
}
}
ckielstra



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

View user's profile Send private message

PostPosted: Sat Jan 10, 2009 7:38 am     Reply with quote

Hi Andrew,
Your implementation is close to what I had in mind, except for 1 problem, your variable 'd' is not a string so you can not use strcpy.
change:
Code:
   strcpy(&buffer[i],&d);
to:
Code:
   buffer[i] = d;
and then after the loop add a terminating zero to the buffer:
Code:
buffer[8] = 0;
Andrew83



Joined: 16 Sep 2008
Posts: 51

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

PostPosted: Sat Jan 10, 2009 7:42 am     Reply with quote

Hmmm ...you ar right ...however, the program works just fine ! I think a type conversion is happening here ...it's worth further investigation!

Ok ...let's see: if i write the following program, i tink it's an equivalent to the strcpy() function:
Code:

void main()
  {
     char str1[] = "Copy a string.";
     char str2[15];
    int  i;
    for (i=0; str1[i]; i++)
       str2[i] = str1[i];
        str2[i] = 0;
    printf("The content of str2: %s\n", str2);
    while(1);
}

So this program represent exactly what you sugested
Am i right ? Smile
ckielstra



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

View user's profile Send private message

PostPosted: Sat Jan 10, 2009 8:51 am     Reply with quote

Quote:
Hmmm ...you ar right ...however, the program works just fine ! I think a type conversion is happening here ...it's worth further investigation!
No conversion is done. You are just being lucky the memory location directly after the variable 'd' contains a zero. This is random behaviour and can not be relied on.

Yes, your program is equivalent to the strcpy function but there is no need to write your own implementation. The compiler supplied version suffices and is way more optimized.

Here is the complete code as I suggested:
Code:
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

void main()
{
  char c,d,i,buffer[9];
 
  while(1)
  {
    c = getc();
    for(i = 0; i < 8; i++)
    {
      if (c & 0x80)
      {
        d = '1';
      }
      else
      {
        d = '0';
      }
      c <<= 1;
      buffer[i] = d;
    }
    buffer[8] = 0;    // terminate string
    printf("%s \n\r", buffer);
  }
}
Guest








PostPosted: Sat Jan 10, 2009 9:17 am     Reply with quote

Ok ! Thank you very very much !! Very Happy
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