C scanf无法正常工作(帮助!)

时间:2017-10-03 00:54:25

标签: c string-formatting

正在开发一个程序,提示用户输入电话号码,然后使用打印出来。而不是 - 所以当我运行它时它甚至不让我输入任何它只是运行并给我随机值。所以现在看一下完整的程序。

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

2 个答案:

答案 0 :(得分:1)

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

    "\n(888) 555-1212"

(输入'\n'后按 Enter 的结果为(mm/dd/yyyy)

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

但是,前导空格不在整数之前,它位于"("之前,而格式字符串不会跳过它。使用scanf格式字符串中的" "空格)将导致跳过/丢弃任意数量的空白字符。因此,正如BLUEPIXY正确指出的那样,您需要在格式字符串中的"("之前添加空格,以使scanf忽略'\n'stdin等待。

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

至少,您必须检查scanf(实际上是所有用户输入函数)的返回,以提供最小的验证,实际上您确实在变量中存储了有效的输入,以便在代码中继续。如果您未能检查返回,则无法确信从该点开始未调用未定义的行为。所以验证所有用户输入

将代码放在一起的代码的最小重写将是:

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

示例使用/输出

$ ./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。花了很多时间。

答案 1 :(得分:0)

如果您正在使用Xcode,那么请编写如下的printf语句:

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

在最后添加换行符(\ n)。