[Courses] [C] Debugging (Re: help me find my C bug? (long))
Christopher James Lahey
clahey at ximian.com
Wed Jul 10 01:25:28 EST 2002
On Wed, 2002-07-10 at 00:12, Suzi Anvin wrote:
> heh. Hey, I'm just happy the bug was related to something I hadn't
> learned yet. :) My chosen fix is to round the sucker in the conversion
> to int:
> instead of total = amount * 100
> total = (amount * 100) + 0.5
>
> Cheesy but it works in this instance. More elegant solutions welcome
> just out of curiosity...
> -Suzi
This is a completely valid way to solve this problem, however, there's a
function in the c library called round which does something very similar
to what you've done.
So that would be:
total = round(amount * 100);
Or even better, that I didn't realize until just now reading over the
spec is:
total = lround (amount * 100);
which actually returns a long instead of a double.
However, the solution I would go with is changing entirely the parsing
mechanism. One possibility:
sscanf(line, "%d.%d", &dollars, ¢s);
and procede from there. This changes the semantics of error cases some,
but keeps the semantics of the standard cases the same.
The other however here is that I wouldn't use sscanf in the first place,
but instead parse the string by hand using pointers. This is probably
something of a bias for me. I don't trust any of the scanfs. I would
do something like:
dollars = 0;
pointer = line;
while (isdigit(*pointer)) {
dollars *= 10;
dollars += *pointer - '0';
pointer ++;
}
if (*pointer == '.') {
pointer ++;
}
total = 0;
cent_digit = 0;
while (isdigit (*pointer)) {
cent_digit ++;
total *= 10;
total += *pointer - '0';
pointer ++;
}
if (cent_digit > 2) {
fprintf (stderr, "Not a proper dollar amount.\n");
continue;
}
if (*pointer != 0 && *pointer != '\n') {
fprintf (stderr, "Not a proper dollar amount.\n");
continue;
}
And then go on from there. It's a bit longer, and doesn't do much
extra, but it's much more explicit about what it does and doesn't do and
isn't as forgiving if the user types an invalid input.
I like writing parsing code like this though.
Oh, one last thing. As a matter of style and maintainability, I would
put all of those variables inside of the main function since they don't
need to be global.
Good luck with it,
Chris
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: This is a digitally signed message part
Url : http://linuxchix.org/pipermail/courses/attachments/20020710/0ab47c16/attachment.pgp
More information about the Courses
mailing list