0

I'm sending an AT command to a modem and getting this response (I'm using C):

\r\nOK\r\n\r\n+RSRP: 164,6200,\"-090.20\",\r\r\n+RSRQ: 164,6200,\"-07.30\",\r\n\r\nOK\r\n

The whole line is a C string. I need to use sscanf to readout the values in quotes, (-090.20 and -07.30). I'm having a really hard time. How would you solve this? Thanks a bunch!

Timotheus
  • 13
  • 3
  • 2
    Can you demonstrate *any* effort at solving this yourself? – Scott Hunter Jul 06 '20 at 14:07
  • `Any suggestions?` This question is too broad. Research C language. Learn about the tools `scanf` that you want to use. [Buy a good book about C programming](https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). Research existing libraries that use AT commands, at least on github. Research the documentation of Heyes protocol and documentation of your device. Eat healthy. Exercise. You might be interested in [scanf](https://en.cppreference.com/w/c/io/fscanf) maybe in [fmemopen](https://man7.org/linux/man-pages/man3/fmemopen.3.html). Please read [how-to-ask]. – KamilCuk Jul 06 '20 at 14:29
  • Please read about [how do we ask a good question on stackoverflow](https://stackoverflow.com/help/how-to-ask). – KamilCuk Jul 06 '20 at 14:35

2 Answers2

1

Not with scanf, but also a possibility:

You could use strtok to separate the wanted values and atof to convert them to double. Be aware that unlike strtod (which is a bit more complicated to use), atof does not offer error handling. The values can be extracted using the following function, for example:

#include <string.h> // For strtok
#include <stdlib.h> // For atof

void scanValues(char* input, double* value1, double* value2) {
    char* sep;
    
    sep = strtok(input, "\""); // replaces the first \" with \0
    sep = strtok(NULL, "\"");  // replaces the second \" with \0,
    *value1 = atof(sep);       // sep points to the first wanted value
    
    // Same for the second value:
    sep = strtok(NULL, "\"");
    sep = strtok(NULL, "\"");
    *value2 = atof(sep);
}

It could be called as follows:

#include <stdio.h>  // For printf

int main() {
    double value1, value2;
    char input[] = "\r\nOK\r\n\r\n+RSRP: 164,6200,\"-090.20\",\r\r\n+RSRQ: 164,6200,\"-07.30\",\r\n\r\nOK\r\n";
    
    scanValues(input, &value1, &value2);
    
    printf("%f %f\n", value1, value2);
}
fcdt
  • 2,371
  • 5
  • 14
  • 26
0

The whole line is a C string

I need to use sscanf to readout the values in quotes

The code:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
    char input[] = "\r\nOK\r\n\r\n+RSRP: 164,6200,\"-090.20\",\r\r\n+RSRQ: 164,6200,\"-07.30\",\r\n\r\nOK\r\n";
    char value1[101];
    char value2[101];
    int ret = sscanf(input, "%*[^\"]\"%100[^\"]\"%*[^\"]\"%100[^\"]", value1, value2);
    if (ret != 2) {
        fprintf(stderr, "Matching error\n");
        abort();
    }
    printf("value1=%s\n", value1);
    printf("value2=%s\n", value2);
}

outputs:

value1=-090.20
value2=-07.30

Short description of parts used in format string used in sscanf:

  • %*[^\"] - Ignore everything up until a "
  • \" - match a "
  • %100[^\"] - match up to 100 characters up to a "

You could use GNU extension %m[\^"] to dynamically allocate the string instead of specifying constant max size.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • There was a GNU extension which allowed `%a...` for automatic allocation, but Posix Issue 7 (2008) adopted the `m` modifier for that purpose, so it's a Posix standard extension, not just glibc. – rici Jul 06 '20 at 18:35
  • Thank you @KamilCuk for taking the time to explain with a concrete example! Much appreciated. Works perfectly!! – Timotheus Jul 07 '20 at 11:09