|
|
View previous topic :: View next topic |
Author |
Message |
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
help with string [Solved] |
Posted: Mon Apr 27, 2020 11:58 pm |
|
|
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
|
|
Posted: Tue Apr 28, 2020 12:24 am |
|
|
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
|
|
Posted: Tue Apr 28, 2020 12:25 am |
|
|
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... |
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Tue Apr 28, 2020 12:40 am |
|
|
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
|
|
Posted: Tue Apr 28, 2020 12:49 am |
|
|
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
|
|
Posted: Tue Apr 28, 2020 6:49 pm |
|
|
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;
} |
|
|
|
|
|
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
|