Search code examples
c++scanfsim900

sscanf parse response with whitespaces


I need to parse a response from a device (SIM900) like this:

\r\n+CIPRXGET:1

+CIPRXGET: 2,1,3
DATA COMPOSED BY A WHITESPACE AND MAYBE OTHER
OK

so i use sscanf twice: first to remove the final string "OK" and second to parse data.

char buffer[256] = sim900.getResponse();
char data[256];
int bytesRead, bytesToRead;
sscanf(buffer, "%[^OK]", buffer);
sscanf(buffer, "%*s,%d,%d\r\n%[^\\0]", &bytesRead, &bytesToRead, data);

my response start with a whitespace (character 0x20) and i got a dirty output, that is "\r\n \r\n" (or in hex representation "0x0D 0x0A 0x20 0x0D 0x0A").

I tried everything but i can't parse correctly only the whitespace character into the output buffer.


Solution

  • Problems:

    1. sscanf(buffer, "%[^OK]", buffer); attempts to read and write to the same buffer. This is undefined behavior. Use different buffers. @EOF

    2. "%[^OK]" Looks for all char that is not 'O' and is not 'K', so it stops at \r\n+CIPRX ... DATA C

    3. "%*s" in sscanf("%*s,%d..." does 2 things 1) scan and not save all leading white-space characters. 2) scan and not save (because of '*') all non-white-space characters. There will never be a ',' following "all non-white-space characters", so sccanf() stops.

    When using sscanf() and having troubles, the first thing to code is a check of the return values of sscanf().

    Unclear as to OP overall goal, but perhaps the following will help.

    #include <stdio.h>
    
    char *text = 
    "\r\n+CIPRXGET:1\r\n+CIPRXGET: 2,1,3\r\nDATA COMPOSED BY A WHITESPACE AND MAYBE OTHER\r\nOK";
    
    int main(void) {
      char data[256];
      int bytesRead, bytesToRead;
      if (sscanf(text, "%*[^,],%d,%d %255[^\r\n]", &bytesRead, &bytesToRead, data) == 3) {
        printf("bytesRead:%d\nbytesToRead:%d\ndata:'%s'\n",bytesRead, bytesToRead, data);
      }
      return 0;
    }
    

    Output

    bytesRead:1
    bytesToRead:3
    data:'DATA COMPOSED BY A WHITESPACE AND MAYBE OTHER'