[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, &cents);

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