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
-- 未能检查 return。 scanf
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。时间花得值。
正在开发一个程序,提示用户输入 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
-- 未能检查 return。 scanf
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。时间花得值。