C scanf 没有按预期工作(求助!)

C scanf not working as intended (Help!)

正在开发一个程序,提示用户输入 phone 数字,然后使用 .而不是 - 所以当我 运行 它甚至不让我输入任何东西它只是 运行s 并给我随机值。所以这里是完整的程序。

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);

如果您使用的是 Xcode,请像这样编写您的 printf 语句:

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

最后加一个换行符(\n)。

您遇到的问题,可能是新手C程序员遇到的最常见的问题之一——scanf的不当使用。具体来说,当您尝试读取电话号码时,stdin 包含,例如:

    "\n(888) 555-1212"

(输入(mm/dd/yyyy)后按回车'\n'结果)

因此,在 stdin 中等待的输入 匹配 "(%d..." 匹配失败 结果。为什么? stdin中的字符开头有一个换行符"%d" 格式说明符(所有数字转换说明符)将跳过前导白色space。

但是,前导白色space 不在整数 之前,它在 "(" 之前,您的 没有跳过它格式字符串。对于 scanf 格式字符串 中的 " " (space) 将导致任意数量的白色space 个字符为skipped/discarded。因此,正如 BLUEPIXY 正确指出的那样,您需要在 格式字符串 中的 "(" 之前添加 space 以获得 scanf 忽略等待 stdin.

'\n'

除此之外,您犯了几乎所有新 C 程序员都会犯的同样的错误和误用 scanf -- 未能检查 returnscanf returns 根据 格式字符串 中的 转换说明符 发生的成功转换的次数。

至少,您必须检查 scanf 的 return(实际上是在所有用户输入函数上),以提供最低限度的验证,证明您确实在变量中存储了有效输入在您的代码中继续。如果您未能检查 return,您将无法确信从那时起未调用未定义的行为。因此 验证所有用户输入

将这些部分放在一起的最小代码重写将是:

#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;
}

示例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

(注意 我调整了格式,将 Item 放在第二行...)

审视事物,花时间去理解 man 3 scanf。时间花得值。