简体   繁体   中英

C scanf not working as intended (Help!)

Was working on a program that prompts a user to enter a phone number and than prints it out using . instead of - so and when I run it it doesn't even let me input anything it just runs and gives me random values. So here's a look at the full program.

int item_number, year, month, day, first, middle, last;
//float unit_price;

printf("Enter item number: ");
scanf("%d", &item_number);

printf("Enter unit price: ");
scanf("%f", &unit_price);

printf("Enter purchase date (mm/dd/yyyy): ");
scanf("%d /%d /%d", &month, &day, &year);

printf("Item\t\tUnit\t\tPurchase\n\t\tPrice\t\tDate");
printf("\n%d\t\t$%6.2f\t\t%.2d/%.2d/%.2d\n", item_number, unit_price, month, day, year);

//here is the code that gives me the problem explained above.
//also if i comment the code above it works.
printf("Enter phone number [(xxx) xxx-xxxx] : ");
scanf("(%d) %d - %d", &first, &middle, &last);

printf("You entered %d.%d.%d", first, middle, last);

The problem you have encountered, is probably one of the most common problems encountered by new C programmers -- the improper use of scanf . Specifically, when you attempt to read the telephone number, stdin contains, eg:

    "\n(888) 555-1212"

(the '\\n' the result of pressing Enter after (mm/dd/yyyy) is entered)

As a result, the input waiting in stdin does not match "(%d..." , and a matching failure results. Why? There is a newline at the beginning of the characters in stdin . The "%d" format specifier (all numeric conversion specifiers ) will skip leading whitespace.

However, the leading whitespace does not precede the integer , it precedes the "(" which is not skipped by your format string . With scanf , a " " ( space ) in the format string , will cause any number of whitespace characters to be skipped/discarded. So as BLUEPIXY correctly notes, you need to add the space before the "(" in the format string to have scanf ignore the '\\n' waiting in stdin .

Beyond that, you make the same mistake and misuse of scanf that nearly all new C-programmers do -- failing to check the return . scanf returns the number of successful conversions that take place based on the conversion specifiers in the format string .

At minimum, you must check the return of scanf (and in fact on ALL USER INPUT functions) to provide minimal validation that you do in fact have valid input stored in your variables to proceed forward with in your code. If you fail to check the return, you can have no confidence that undefined behavior isn't being invoked from that point forward. So validate all user input .

A minimal rewrite of your code that puts those pieces together would be:

#include "stdio.h"

int main (void) {

    int item_number, year, month, day, first, middle, last;
    float unit_price;

    printf("Enter item number: ");
    if (scanf ("%d", &item_number) != 1) {  /* validate item */
        fprintf (stderr, "error: invalid input (item_number)\n");
        return 1;
    }

    printf("Enter unit price: ");
    if (scanf ("%f", &unit_price) != 1) {   /* validate unit */
        fprintf (stderr, "error: invalid input (unit_price)\n");
        return 1;
    }

    printf("Enter purchase date (mm/dd/yyyy): ");
    /* validate date */
    if (scanf ("%d /%d /%d", &month, &day, &year) != 3) {
        fprintf (stderr, "error: invalid input (mm/dd/yyyy)\n");
        return 1;
    }

    printf ("\t\tUnit\t\tPurchase\nItem\t\tPrice\t\tDate");
    printf ("\n%d\t\t$%6.2f\t\t%.2d/%.2d/%.2d\n", 
            item_number, unit_price, month, day, year);

    printf ("Enter phone number [(xxx) xxx-xxxx] : ");
    /* validate phone */
    if (scanf (" (%d) %d - %d", &first, &middle, &last) != 3) {
        fprintf (stderr, "error: invalid input [(xxx) xxx-xxxx]\n");
        return 1;
    }

    printf ("You entered %d.%d.%d\n", first, middle, last);

    return 0;
}

Example Use/Output

$ ./bin/scanf_phone
Enter item number: 3
Enter unit price: 19.95
Enter purchase date (mm/dd/yyyy): 03/01/2017
                Unit            Purchase
Item            Price           Date
3               $ 19.95         03/01/2017
Enter phone number [(xxx) xxx-xxxx] : (800) 555-1212
You entered 800.555.1212

( note I tweaked the format to put Item on the 2nd line...)

Look things over, and spend the time it takes to understand man 3 scanf . It is time well spent.

If you are using Xcode, then write your printf statements like so:

printf("Enter item number:\n");

Put a newline(\\n) at the end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM