This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

scanf() and syntax checking

I need to syntax check incomming queries/commands on the UART and i would like some idears on how to do it.
The syntax of the commands are as follow:

Syntax required for a query is:
@<device address><query>?;FF

Syntax required for a command is:
@<device address><command>!<parameter>;FF

Examples:
Query current baud rate: @253BR?;FF
Change baud rate to 19200: @253BR!19200;FF
where:
@ <attention character>
253 <device address>
BR? <query> (for query syntax)
BR!19200 <command>!<parameter> (for command syntax)
;FF <terminator>

Please note the termination is ;FF and not CR or LF.

Is it possible to use the scanf() function for this task?
Something like this perhaps:

scanf("@%3s%2s?;FF", adr, command);

Parents
  • scanf() can match literals in the input as well as extract fields into variables.

    The biggest drawback to scanf() is the lack of detail about what went wrong. This may or may not be a problem for you; mainly it limits your ability to provide useful feedback or debug information.

    For example, executing

    actual = scanf("@%uBR!%u;\xFF", &devAddr, &baudRate);

    will match your baud rate command. If, however, even one character is out of place, all you'll know is "actual", the number of bytes that were actually matched from the input (not the format string). Scanning

    @2X3BR!19200;FF

    will return "2" (the 'X' stops interpretation of the integer beginning with the '2' and doesn't match a 'B'), but so will

    @2CR!192000;FF

    You won't be able to generate error messages like "2X3 is not a valid device address" or such without more control over the parsing.

    Similarly, the format string you propose will work fine, in some sense, but if the actual input isn't the exact right field width, scanf() will happily produce strings anyway:

    dev = "2X3" command = "BR"
    dev = "2CR" command = "!1"

    and you'll need to add another layer of scanning and checking.

    If your input is mostly reliable, say from another program rather than a human, then this might not be such an issue.

    If you break up the parsing so that you match the input line piece-by-piece, then you probably don't need the complexity of scanf(), but instead just strcmp() or strtok().

    You can get a surprising bit of mileage out of scanf(), but it ultimately falls short for serious parsing tasks. For small jobs where performance doesn't matter, you could manage.

Reply
  • scanf() can match literals in the input as well as extract fields into variables.

    The biggest drawback to scanf() is the lack of detail about what went wrong. This may or may not be a problem for you; mainly it limits your ability to provide useful feedback or debug information.

    For example, executing

    actual = scanf("@%uBR!%u;\xFF", &devAddr, &baudRate);

    will match your baud rate command. If, however, even one character is out of place, all you'll know is "actual", the number of bytes that were actually matched from the input (not the format string). Scanning

    @2X3BR!19200;FF

    will return "2" (the 'X' stops interpretation of the integer beginning with the '2' and doesn't match a 'B'), but so will

    @2CR!192000;FF

    You won't be able to generate error messages like "2X3 is not a valid device address" or such without more control over the parsing.

    Similarly, the format string you propose will work fine, in some sense, but if the actual input isn't the exact right field width, scanf() will happily produce strings anyway:

    dev = "2X3" command = "BR"
    dev = "2CR" command = "!1"

    and you'll need to add another layer of scanning and checking.

    If your input is mostly reliable, say from another program rather than a human, then this might not be such an issue.

    If you break up the parsing so that you match the input line piece-by-piece, then you probably don't need the complexity of scanf(), but instead just strcmp() or strtok().

    You can get a surprising bit of mileage out of scanf(), but it ultimately falls short for serious parsing tasks. For small jobs where performance doesn't matter, you could manage.

Children