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

help with string [Solved]

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



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

help with string [Solved]
PostPosted: Mon Apr 27, 2020 11:58 pm     Reply with quote

I have a problem for read this data,


I capture this data and when I use printf %X show this
301c0017637661726763616c2f66656564732f636f6e74726f6c31333431

printf %c
0cvargcal/feeds/control1341


Code:
void test(){
 
     buffer[50]=301c0017637661726763616c2f66656564732f636f6e74726f6c31333431;
     
    int len strlen(buffer);
     
    for (int  i=0; i<len;i++)   fprintf(uart4,"%x",buffer[i]);                                                   
   
    if (strstr(buffer, "control1") != 0)   fprintf(uart4," found control\r\n");
   
}       


so why dont work strstr, never found the word?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 28, 2020 12:24 am     Reply with quote

Quote:
I capture this data and when I use printf %X show this
301c0017637661726763616c2f66656564732f636f6e74726f6c31333431

You have 0x00 as the 3rd byte. That 0x00 byte terminates the string.
The strstr() function will not search past the end of a string.

To fix it, set the start of the string to buffer+3 as shown below:
Quote:

if(strstr(buffer+3, "control1") != 0)
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Tue Apr 28, 2020 12:25 am     Reply with quote

The %x print can't show what you say.

You show the third character as being 00. This is the end of string character
in C, so strlen would only give the length as two characters.....

strstr, would stop at this NUL character....

Just built a demo based on what you post:
Code:

#include <18F4520.h>
#device PASS_STRINGS=IN_RAM  //needed to allow constant in strstr
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer

#use delay(crystal=20000000)


#use rs232(UART1, baud=9600, ERRORS, stream=UART4)
#include "string.h"

void test(){
 
    char buffer[50]={0x30,0x1c,0x00,0x17,0x63,0x76,0x61,0x72,0x67,0x63,0x61,0x6c,0x2f,0x66, \
    0x65,0x65,0x64,0x73,0x2f,0x63,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x31,0x33,0x34,0x31};
     
    int len;
    len=strlen(buffer);
     
    for (int  i=0; i<len;i++)
       fprintf(uart4,"%x",buffer[i]);
   
    if (strstr(buffer, "control1") != 0)
       fprintf(uart4," found control\r\n");
   
}         

void main()
{
   setup_adc_ports(NO_ANALOGS, VSS_VDD);

   while(TRUE)
   {
      test();
      delay_cycles(1);
   }
}

Stuck the output to UART1, and if I stop at:
for (int i=0; i<len;i++)

len is 2.

I see PCM spotted the same problem as I was typing... Very Happy
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Tue Apr 28, 2020 12:40 am     Reply with quote

Thanks you for answers...
So the best way is copy the string and change the 0x00 by other byte??
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Tue Apr 28, 2020 12:49 am     Reply with quote

At the end of the day a lot depends on 'unsaid' things about this.

You are receiving this data?.
If so, does it have a NUL at the end of the buffer?.
If it doesn't, 'string' based operations if they get past the NUL earlier
in the data, risk walking off through memory, taking a long time, and
finding unexpected things.
To use 'string' operations, you need to design how you receive and store the
data, so that if a NUL is received earlier, it is perhaps replaced with
another 'unused' character. Perhaps 0xFF for example.
Then you need to ensure that before any string function is used, you have
added a genuine NUL terminator to the data.

Alternatives are as PCM_Programmer says, to simply skip the first three
characters, if the NUL is always going to be at this point. Or you could
just use the source code for strstr (it's in string.h), and instead of
searching till the NUL is seen, use the length of the actual data
(I'm guessing that your actual %x print, was really using the received
length, not strlen as you show, since as posted it won't work...).
If so, use the length this was using.
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Tue Apr 28, 2020 6:49 pm     Reply with quote

Why no work this:

data
301c0017637661726763616c2f66656564732f636f6e74726f6c31333431

char
0cvargcal/feeds/control1341



Code:

     uint16_t  len = readPacket(buffer,5000);   // return one full packet      301c0017637661726763616c2f66656564732f636f6e74726f6c31333431
        if (len>0){
 
                  int8 topic_len=24;            //cvargcal/feeds/control1   
                  int8 f=1+4+ topic_len ;    //29
                 
                       //  ___________  _________             
                       // 30 1c 00 17 63  topic/data                                                             
                       // C    1   2   3  4   
                                                           
                                 
              while (1){         
                     
                    char dat2[40];
                 if(strstr(buffer+3, "control1") != 0) { 
                                                           
                   fprintf(" found control1\r\n");
                        int k=0;                   
                        for (uint16_t i=0; i+f <len;i++){
                               dat2[k] = buffer[i+f];                               
                               k++;           
                        }                                       
                    fprintf("\r\n dat %s\r\n",dat2);     
                         for (uint16_t h=0; dat2[h]!=0;h++) fprintf("%c",dat2[h]);         
                     break;                                                                                                   
                                                 
                 }         
            }



Why no print the dat2?


I need get the value that mqtt server send
C control byte + 4 byte len + payload (topic+data)



edit



I GET IT!! (Well copy code from mqtt adafruit)

Code:
 if (len>0){
                uint16_t i, topiclen, datalen;
       
                 // Parse out length of packet.
                   topiclen = buffer[3];                   
       
                                     
                     uint8_t packet_id_len = 0;
                    uint16_t packetid = 0;
                    // Check if it is QoS 1, TODO: we dont support QoS 2
                    if ((buffer[0] & 0x6) == 0x2) {
                      packet_id_len = 2;
                      packetid = buffer[topiclen+4];
                      packetid <<= 8;
                      packetid |= buffer[topiclen+5];
                    }                   
                                             
                    memset(dat2, 0, 100);                                               
                                                 
                    datalen = len - topiclen - packet_id_len - 4;                 
       
                     // extract out just the data, into the subscription object itself
                     memmove(dat2, buffer+4+topiclen+packet_id_len, datalen);   
       
       
                     for (int  i=0; i<datalen;i++)  fprintf(uart4,"%c",dat2[i]);   
                     break;                                                                                                   
                                                         
                 }   
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