Jim
Jim

Reputation: 27

What format for scanf will read in the example input line?

I'm working on an old C program and ran into a problem with scanf. I have been experimenting for many hours but still cannot get scanf to read a particular line.

The line being read in is:

01/05\t\t840.81\tvisa payment (online)\tAFCU\n

The C code using scanf is:

sscanf(lineIn, "%d/%d %f %[A-Z\(\)a-z0-9]s\t%[A-Za-z0-9]s",
       &month, &year, &amt, &item, &supplier);

This line scans the month, year, amt and item variables correctly and the values can be verified. But no matter what format I used at the end, I cannot get the value of supplier to be read in.

Can anyone suggest a format that will scan in all of the variables?

Upvotes: 1

Views: 63

Answers (1)

chux
chux

Reputation: 154255

I cannot get the value if of supplier

Scanning stopped on the incorrect s. @William Pursell.

Lack of a ' ' in %[A-Z\(\)a-z0-9] contributes to not scanning all of the item.


Do not use "%s" nor "%[]" without a Width.

Use a width one less than the array count.

s is wrong after a %[]

Drop the s in "%[A-Z\(\)a-z0-9]s". "%[A-Z\(\)a-z0-9]" and "%s" are separate scan directives.

Do not use undefined escapes

\( and and \) are not defined.

float with money is marginally OK

Better as double. Money has a whole hosts of issues too.

Check conversion success

Do not use the address of any array for %[]

Pass the address of the first element of the array.
This implies compiling done without all warnings enabled.
Save time. Enable all warnings.

Allow spaces in item[], supplier[]

... the space in the %100[A-Za-z0-9 ] conversion has a different meaning from the space before %n: a space in a scan set matches the space character whereas a space elsewhere in the format string matches any white space characters, including TAB and newline. @chqrlie


  • I recommend using " %n" to detect complete conversion success.

  • Be generous, allow white-space between tokens. %d, %f, %s already allow leading white-space. %[] does not.

int main(void) {
  const char *lineIn = "01/05\t\t840.81\tvisa payment (online)\tAFCU\n";

  int month, year;
  double amt;
  char item[90 + 1];
  char supplier[100 + 1];

  // sscanf(lineIn,"%d/%d %f %[A-Z\(\)a-z0-9]s\t%[A-Za-z0-9]s",
  //    &month,&year,&amt,&item,&supplier);

  int n = 0;
  sscanf(lineIn, "%d /%d%lf %90[A-Z()a-z0-9 ] %100[A-Za-z0-9 ] %n", //
      &month, &year, &amt, item, supplier, &n);
  if (n == 0 || lineIn[n]) {
    puts("Failed");
  } else {
    puts("Success");
  }

}

Upvotes: 1

Related Questions