Coma Coma - 2 months ago 16
C Question

How do I use scanf to properly parse and filter dynamic input?

This is for homework, so I'm stuck with the requirements I describe.

I need to handle input of the following general form:

XYZ A1 5


The first part (
XYZ
) is a command,
A1
is an address (I only need the 1), and
5
is the value of the command. Additionally, I need to handle commands that have neither address nor value (just
XYZ
, for example), and commands that have only an address but no value (
XYZ A1
).

I managed to duck-tape this together which seems to handle everything cough pretty well:

n = scanf("%c%c%c A%i %i",&c1,&c2,&c3,&a,&val);


So I can use
n
(how many arguments/variables
scanf
managed to match) to figure out what sort of command it is, then do some basic checks to get what I need. And it works pretty well!

But here is my problem:
There is also a command in the format
XYZ A1 A2
- as in it has two 'address' values. How do I get
scanf
to parse this as well? Once again, I don't really need the 'A' to be parsed.

If I do:

scanf("%c%c%c A%i A%i",&c1,&c2,&c3,&a,&val);


then the various other commands wont work when the address and value inputs don't have an 'A' before them.

P.S. Not allowed to use any form of strings / arrays, hence the chars;

What can I do here?

Answer

Don't try to do it all in a single scanf call. Instead, read the command first, check if it takes additional parameters, then read those:

n = scanf( "%c%c%c", &c1, &c2, &c3 );
if ( n != 3 )
  // input error, bail out here

if ( has_address( c1, c2, c3 ) )
{
  if ( scanf( "A%i", &a1 ) != 1 )
    // input error, bail out here
}

if ( has_2nd_address( c1, c2, c3 ) )
{
  if ( scanf( "A%i", &a2 ) != 1 )
    // input error, bail out here
}

if ( has_value( c1, c2, c3 ) )
{
  if ( scanf( "%i", &val ) != 1 )
    // input error
}

has_address, has_2nd_address, and has_value are simply placeholders for whatever logic you need to use to determine whether you need to read one or two address, and whether you need to read a value.