1

I have a certain message protocol in which 4 values are sent in ascii format. They are separated by commas and are terminated by a newline character.

To process a received message I use sscanf()

    if( messageReceived() )
    {
        sscanf( message, "%d,%d,%d,%d", 
            &SLAVE_ID, &COMMAND, &DATA1, &DATA2 ) ;
    
        processMessage() ;
    }

This works fine.

Depending on what value goes into COMMAND, the values of DATA1 or DATA2 may or may not be used inside the function processMessage()

The messages do have a fixed format, meaning that there are always 4 values in a message like: 1,23,123,213

I want to start with variable sized messages and I am wondering if my line with sscanf() is going to do strange things (undefined behaviour) if I for instance would send 2,23. Obviously I would not be interested in the values of DATA1 or DATA2 in this example.

I do know how that I can calculate the message size by simply counting the amount of commas + 1 and do something like:

switch (messageSize)
{
case 2:
    sscanf( message, "%d,%d", 
                &SLAVE_ID, &COMMAND ) ;
    break;
case 3:
    sscanf( message, "%d,%d,%d", 
                &SLAVE_ID, &COMMAND, DATA1 ) ;
    break;
case 4:
    sscanf( message, "%d,%d,%d,%d", 
                &SLAVE_ID, &COMMAND, DATA1, DATA2 ) ;
    break;
// etc
}

However I would still like to know if this...

    sscanf( message, "%d,%d,%d,%d", 
                &SLAVE_ID, &COMMAND, DATA1, DATA2 ) ;

... is going to give undefined behaviour if message only contains 1,2?

bask185
  • 377
  • 1
  • 3
  • 12

1 Answers1

0

No, that behavior is well-defined. Quoth the C standard:

The sscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the sscanf function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.

So you can just use one format string, but you should check sscanf's return value to see if the expected number of values was read:

  if(messageSize == sscanf( message, "%d,%d,%d,%d", 
                            &SLAVE_ID, &COMMAND, &DATA1, &DATA2 ))
  {
    // everything is fine.
  }
Wintermute
  • 42,983
  • 5
  • 77
  • 80