1

This code doesn't repeat if I answer a negative number like "-1.01". How can I make it loop so that it will ask again for c?

#include <stdio.h>

main()
{
    float c;

    do {
        printf("O hai! How much change is owed? ");
        scanf("%.2f", &c);
    } while (c < 0.0);

    return(0);
}
Brian White
  • 8,332
  • 2
  • 43
  • 67
Andrew
  • 19
  • 5
  • ``%.2f`` looks a bit funny. As if you programmed the person entering the number to use a specific format. Do you also like voodoo dolls? :) – BitTickler Mar 20 '15 at 06:03

2 Answers2

1

The format strings for scanf are subtly different than those for printf. You are only allowed to have (as per C11 7.21.6.2 The fscanf function /3):

  • an optional assignment-suppressing character *.
  • an optional decimal integer greater than zero that specifies the maximum field width (in characters).
  • an optional length modifier that specifies the size of the receiving object.
  • a conversion specifier character that specifies the type of conversion to be applied.

Hence your format specifier becomes illegal the instant it finds the . character, which is not one of the valid options. As per /13 of that C11 section listed above:

If a conversion specification is invalid, the behaviour is undefined.


For input, you're better off using the most basic format strings so that the format is not too restrictive. A good rule of thumb in I/O is:

Be liberal in what you accept, specific in what you generate.

So, the code is better written as follows, including what a lot of people ignore, the possibility that the scanf itself may fail, resulting in an infinite loop:

#include <stdio.h>
int main (void) {
    float c;
    do {
        printf ("O hai! How much change is owed? ");
        if (scanf ("%f", &c) != 1) {
            puts ("Error getting a float.");
            break;
        }
    } while (c < 0.0f);
    return 0;
}

If you're after a more general purpose input solution, where you want to allow the user to input anything, take care of buffer overflow, handle prompting and so on, every C developer eventually comes up with the idea that the standard ways of getting input all have deficiencies. So they generally go write their own so as to get more control.

For example, here's one that provides all that functionality and more.

Once you have the user's input as a string, you can examine and play with it as much as you like, including doing anything you would have done with scanf, by using sscanf instead (and being able to go back and do it again and again if initial passes over the data are unsuccessful).

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Is there a way to make the loop continue even when characters are inputted by the user? For example I ran this program and type in "hi" I want the loop to go back and ask the user for "how much change is owed?" and then scan for the user input again until a floating number is given to two decimal places. – Andrew Mar 20 '15 at 07:03
  • @Andrew, that's where you generally move away from `scanf` directly and use `fgets` to get a line, followed by `sscanf` to process it in the same way you did originally. At that point, you'll probably want a tried and true solution, one of which I've added as a link in my answer. – paxdiablo Mar 20 '15 at 07:22
0
scanf("%.2f", &c );
//      ^^ <- This seems unnecessary here.

Please stick with the basics.

scanf("%f", &c);

If you want to limit your input to 2 digits,

scanf("%2f", &c);
shauryachats
  • 9,975
  • 4
  • 35
  • 48