我需要编写一个程序,使用scanf()读取整数列表(不使用数组)。第一个数字是代表性的汇率,剩下的所有数字都代表以美元表示的现金金额。程序应在"$"列中以美元打印现金金额,并在"IS"列中打印另一枚硬币的现金金额(美元*汇率)。此外,程序应该打印每列的总和。
#include <stdio.h>
int main()
{
float rate = 0;
float numDollar = 0;
float numShekel = 0;
float sumDollar = 0;
float sumShekel = 0;
printf(" nPlease enter the U.S Dollar Representative Exchange Rate n ");
scanf(" %f", &rate);
printf(" nPlease enter the numbers which represents cash amount in Dollars (and then press enter) n ");
printf("n$tttttISn");
while (scanf(" %f", &numDollar) !=EOF && (numDollar!='n'))
{
sumDollar = sumDollar + numDollar;
numShekel = numDollar * rate;
sumShekel = sumShekel + numShekel;
printf("%3.2fttttt%3.2fn",numDollar,numShekel);
}
printf("%3.2fttttt%3.2fn",sumDollar,sumShekel);
return 0;
}
我有一些问题:
基于上述程序:
用户输入"费率"->按回车键->"输入号码列表"->按回车键。
问题:我只想打印列标题($和IS)在以上流程之后(即,只有AFTER用户输入整数列表并按下回车键)。
我不能只在while循环之后打印,因为那样列标题将打印在列值的下方错误的这是因为我被限制打印下一个整数在while循环期间,因为scanf将丢失以前的值一旦下一个被阅读(正确吗?!)。。。
是否有任何方法可以遍历存储在scanf缓冲区中的所有整数这样我就可以打印标题然后一次拍摄的值?
在上面的程序中,似乎在所有列值打印时,直到按下CTRL+D时才打印每列的总和输入。如何使总和也与列一起打印一次拍摄的值?我试图将while条件更改为!='\n’但它不起作用,因为我处理的是float而不是char。
您可以假设整数列表是在一行中输入的。
请协助。
感谢
我做了一些改动。
现在我只剩下第二个问题了。如何在一次打印中打印带有列标题的总和?我不想按CTRL+D,然后再打印总数。我希望在一次打印中打印列标题+列值+列总和。
#include <stdio.h>
int main()
{
float rate = 0;
float numDollar = 0;
float numShekel = 0;
float sumDollar = 0;
float sumShekel = 0;
printf(" nPlease enter the U.S Dollar Representative Exchange Rate, and a list of cash amounts in Dollars in a single line (CTRL+D to finish) n ");
scanf(" %f", &rate);
printf("n$tttttISn");
while (scanf("%f", &numDollar) != EOF)
{
sumDollar = sumDollar + numDollar;
numShekel = numDollar * rate;
sumShekel = sumShekel + numShekel;
printf("%3.2fttttt%3.2fn",numDollar,numShekel);
}
printf("%3.2fttttt%3.2fn",sumDollar,sumShekel);
return 0;
}
只使用scanf
和printf
而不使用数组是不可能实现的。您需要使用类似于readline
库或terminfo
库的东西来接管逐字符输入系统。
根本问题是scanf(' %f', ...)
将进行扫描,直到它读取到浮点值,并在此之前丢弃所有空白。这里的"空白"不仅指空格和制表符,还指换行符!因此,用户可以在代码到达之前键入RETURN、数字、RETURN和第二个数字。然后,您的代码需要删除所有这些格式错误的输入,然后返回到正确的行(到那时可能已经滚动掉了),并打印正确格式的值。
因此,您需要比scanf
更好的东西,它将能够阻止RETURN(以及ENTER和长行)滚动屏幕,并且您需要terminfo
或等效程序来获得执行"擦除此行"one_answers"将光标移动到此点"等操作所需的控制序列。
不幸的是,scanf
不能替代健壮的解析器。它是围绕读取输入文件而设计的,对终端输入不是很聪明。
-
这将根据需要首先打印总额,但将按相反顺序打印输入的美元
到目前为止,美元输入顺序和打印顺序尚未指定。 -
检测CCD_ 9的拼凑远远低于此。
推荐带有货币变量的double
。
始终检查scanf()
结果。例如EOF
、0
、1
scanf(" %f",...
中不需要空间
#include <stdlib.h>
#include <stdio.h>
void GetMoney(double rate, double *sumDollar, double *sumShekel) {
double numShekel, numDollar;
int cnt = scanf("%lf", &numDollar);
if (cnt == EOF) {
printf("%3.2lfttttt%3.2lfn", *sumDollar, *sumShekel);
return;
}
if (cnt != 1) Handle_NonNumericInput(); // e.g. do same as EOF
numShekel = numDollar * rate;
*sumDollar += numDollar;
*sumShekel += numShekel;
GetMoney(rate, sumDollar, sumShekel);
printf("%3.2lfttttt%3.2lfn", numDollar, numShekel);
}
int main() {
double sumDollar = 0.0;
double sumShekel = 0.0;
double rate;
//...
printf("n$tttttISn");
GetMoney(rate, &sumDollar, &sumShekel);
//...
}
--
关于货币,在这种情况下,具有0.005美元等小数部分的值会引起问题。各种方法,都是最低的法定单位,如0.01美元-->1美元和1.00美元-->100美元或圆形计算:
sumDollar = round((sumDollar + numDollar)*100)/100;
numShekel = round((numDollar * rate)*100)/100;
如何最好地处理金钱的问题超出了本文的范围。这只是一个仅供参考的存在特殊的财务计算问题。
使用scanf()
(和ungetc()
)可以读取一行用空格隔开的数字('n'
除外),然后最终以'n'
结束,但不值得编码,除非作为练习,因为使用fgets()
和sscanf()/strtod()
要好得多。但是fgets()
使用了一个char
数组,被帖子禁止。
以下方法有些奏效,但并不健壮:
char ch == 'n';
int cnt = scanf("%f%c", &numDollar, &ch);
if (cnt == EOF) Handle_EOForIOError();
if (cnt == 0 || !isspace((unsigned char) ch)) Handle_BadInput();
Process(numDollar);
if (ch == 'n') Handle_ThisIsTheLastOne();
// Handle More
如果一个空格和n
跟在一个数字后面,上面的就被愚弄了。
scanf()如果成功,则返回读取的字符总数,否则返回负数。所以可以检查,
scanf(...)>0 or scanf(...)!=-1
条件
scanf()需要cntrl+D,它将"\n"视为其他空格,因此要结束读取enter
上的输入,请使用fgets()
。然后可以使用atof()
或strtof()
将字符串转换为浮点