Keil Logo Arm Logo

Discussion Forum

scanf() and syntax checking

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Peter Bøgely
Posted
28-Nov-2006 07:29 GMT
Toolset
C51
New! 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);

Read-Only
Author
erik malund
Posted
28-Nov-2006 13:36 GMT
Toolset
C51
New! RE: scanf() and syntax checking

Is it possible to use the scanf() function for this task?
possibly, but why even try.
1) it is fairly simple to do it 'by hand"
2) someone is going to make a small change some day that makes the answer "no" instead of "possibly"

Ha' en rar dag

Erik

Read-Only
Author
Drew Davis
Posted
28-Nov-2006 21:02 GMT
Toolset
C51
New! RE: scanf() and syntax checking

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.

Read-Only
Author
Hans-Bernhard Broeker
Posted
28-Nov-2006 23:48 GMT
Toolset
C51
New! RE: scanf() and syntax checking

"actual", the number of bytes that were actually matched from the input

Not quite. Actual will be the number of "conversions" successfully completed. Unless all specifiers in the format string match only one single character, that's not the same as the number of characters matched.

If you want the length of successfully matched input, you need the %n format specifier.

Read-Only
Author
Peter Bøgely
Posted
29-Nov-2006 08:06 GMT
Toolset
C51
New! RE: scanf() and syntax checking

Thanks for your reply.

I have tried your suggestion, but i can't get it to work with the terminating string ";FF".
Matching chars in the beginning of the format string works fine, but it seem like the scanf function will ignore any matching chars at the end of the format string.

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

Maybe its a bug in the scanf function.

Read-Only
Author
Andy Neil
Posted
29-Nov-2006 11:05 GMT
Toolset
C51
New! ;FF?

Is ";FF" supposed to be a 3-character string (a semicolon and two 'F' characters), or just 2 bytes (a semicolon and a 0xFF byte) ?

Read-Only
Author
Peter Bøgely
Posted
30-Nov-2006 06:55 GMT
Toolset
C51
New! RE: ;FF?

Yes i need a ";FF" 3 char string as termination and not the usual CR.

The following code illustrates the scanf function will ignore the matching chars in the end of the format string:

printf("\nEnter a number: ");
while (1) {

if (scanf("%d;FF",&n)) break;

scanf("%s", &tmp); //Clear input stream
}

printf("You wrote %d", n);

Output:
Enter a number: 3;FFYou wrote 3
Enter a number: 4 (CR)
You wrote 4
Enter a number:

In the first line scanf returns correctly as ";FF" is entered.
But in the second line i press CR after the number 4, and scanf ignores the ";FF" in the format string.

Read-Only
Author
Hans-Bernhard Broeker
Posted
29-Nov-2006 20:59 GMT
Toolset
C51
New! RE: scanf() and syntax checking

but it seem like the scanf function will ignore any matching chars at the end of the format string.

How did you arrive at that conclusion? In other words, what made it seem like this?

Read-Only
Author
Neil Kurzman
Posted
30-Nov-2006 03:55 GMT
Toolset
C51
New! RE: scanf() and syntax checking

scanf() is for students. It has too many issue to be used in the real world.

use the other input functions (getch(), gets()) then parse the data your self. This allows you to verify the data is valid. scanf() may not like some data. It will then hang waiting for more data. Or, try to use the next peice on input.

Next Thread | Thread List | Previous Thread Start a Thread | Settings

arm-logo-small

Keil logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.