问题描述
我正在遍历C编程绝对入门指南第三版,在Chapter8ex2.c学习编程并且遇到问题,我的程序在此花了成本,然后被认为是顶峰,反而绕过了,重用了第一个变量而不是使用正确的第二个变量。
这是我的代码
// This is a sample program that asks users for some basic data and prints it on
// the screen in order to show what was entered
#include <stdio.h>
int main()
{
char topping[24];
int slices;
int month,day,year;
float cost;
// The first scanf will look for a floating-point variable,the cost of the pizza
// If the user doesn't enter a $ before the cost,it Could cause problems
printf("How much does a pizza cost in your area?");
printf("enter as $XX.XX)\n");
scanf(" $%f",&cost);
// The pizza topping is a string,so your scanf doesn't need an &
printf("What is your favorite one-word pizza topping?\n");
scanf(" %s",topping);
printf("How many slices of %s pizza",topping);
printf("can you eat in one sitting?\n");
scanf("%i",&slices);
printf("What is today's date (enter it in XX/XX/XX format).\n");
scanf(" %i/%i/%i",&month,&day,&year);
printf("\n\nWhy not treat yourself to dinner on %i/%i/%i",month,year);
printf("\nand have %i slices of %s pizza!\n",slices,topping);
printf("It will only cost you $%.2f!\n\n\n",cost);
return(0);
}
这是正在运行的代码
How much does a pizza cost in your area?enter as $XX.XX)
15.00
What is your favorite one-word pizza topping?
How many slices of 15.00 pizzacan you eat in one sitting?
解决方法
scanf
存在一些问题。考虑对所有输入使用fgets
并根据需要进行解析。
当scanf
失败时,有问题的输入将留在输入流中,并可能导致后续扫描失败或行为异常。 fgets
将从输入流中读取并删除最大缓冲区的大小。
解析输入可以通过许多功能来完成。这里使用sscanf
和strcspn
,但还有许多其他可用的。 strspn
,strtod
,strtol
,strchr
,strstr
,strpbrk
,strtok
,strsep
等。
避免将%i
尤其用于日期。每天或每月输入08
或09
都会造成麻烦。前导零告诉%i
处理一个八进制(以8为底)值,但是8和9无效的八进制数字。do{}while();
允许重复输入,直到可接受的结果为止。解析
这里有限制,但可以改进。
#include <stdio.h>
#include <string.h>
int main()
{
char line[100] = "";
char topping[100] = "";
int result = 0;
int slices = 0;
int month = 0;
int day = 0;
int year = 0;
float cost;
do {
printf ( "How much does a pizza cost in your area?");
printf ( "enter as $XX.XX)\n");
if ( ! fgets ( line,sizeof line,stdin)) {
fprintf ( stderr,"fgets EOF\n");
return 1;
}
result = sscanf ( line," $%f",&cost);
if ( 0 == result) {
printf ( "be sure to use a $\n");
}
} while ( 1 != result);
printf ( "What are your favorite pizza toppings?\n");
if ( ! fgets ( topping,sizeof topping,stdin)) {
fprintf ( stderr,"fgets EOF\n");
return 1;
}
topping[strcspn ( topping,"\n")] = 0;//remove newline
do {
printf ( "How many slices of %s pizza",topping);
printf ( " can you eat in one sitting?\n");
if ( ! fgets ( line,"%d",&slices);
if ( 0 == result) {
printf ( "enter a number\n");
}
} while ( 1 != result);
do {
printf ( "What is today's date (enter it in XX/XX/XX format).\n");
if ( ! fgets ( line,"%d /%d /%d",&month,&day,&year);
if ( 3 != result) {
printf ( "be sure to use a / between numbers\n");
}
} while ( 3 != result);
printf ( "\n\nWhy not treat yourself to dinner on %i/%i/%i",month,day,year);
printf ( "\nand have %i slices of %s pizza!\n",slices,topping);
printf ( "It will only cost you $%.2f!\n\n\n",cost);
return(0);
}