Reputation: 27
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
Reputation: 154255
I cannot get the value
ifof 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