我需要编写一个程序,使用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$\t\t\t\t\tIS\n");
while (scanf(" %f", &numDollar) !=EOF && (numDollar!='\n'))
{
sumDollar = sumDollar + numDollar;
numShekel = numDollar * rate;
sumShekel = sumShekel + numShekel;
printf("%3.2f\t\t\t\t\t%3.2f\n",numDollar,numShekel);
}
printf("%3.2f\t\t\t\t\t%3.2f\n",sumDollar,sumShekel);
return 0;
}
我有一些问题:
基于以上计划:
用户输入&#34; rate&#34; - &GT;按回车键 - &gt; &#34;输入数字列表&#34; - &GT; 按回车键。
问题:我只想打印列标题($和IS) 在上述流程之后(即仅在用户输入整数列表之后) 并按下回车键)。
我不能在while循环之后进行打印,因为那时候 列标题将打印在列值的下方 错误。这是因为我被限制打印下一个整数 在while循环期间,因为scanf将丢失先前的值 一读完下一个(正确吗?!)......
有没有办法遍历存储在scanf缓冲区中的所有整数?所以我可以打印标题 然后是一次拍摄的价值?
在上面的程序中,似乎在所有列值之后 打印后,每栏的总和不会打印,直到CTRL + D为止 进入。如何使用列也可以打印总和 一次拍摄的价值?我试图将while条件改为!=&#39; \ n&#39; 但它不起作用,因为我处理浮动而不是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$\t\t\t\t\tIS\n");
while (scanf("%f", &numDollar) != EOF)
{
sumDollar = sumDollar + numDollar;
numShekel = numDollar * rate;
sumShekel = sumShekel + numShekel;
printf("%3.2f\t\t\t\t\t%3.2f\n",numDollar,numShekel);
}
printf("%3.2f\t\t\t\t\t%3.2f\n",sumDollar,sumShekel);
return 0;
}
答案 0 :(得分:2)
仅使用scanf
和printf
并且不使用数组,您想要做的事情是不可能的。您需要使用readline
库或terminfo
库之类的东西来接管逐个字符的输入系统。
基本问题是scanf(' %f', ...)
将扫描直到它读取浮点值,直到那时丢弃所有空格。 &#34;空白&#34;这里不仅意味着空格和标签,还包括线端!因此,用户可以在代码进入之前输入RETURN几次,数字,RETURN几个,第二个数字和RETURN。然后你的代码需要删除所有这些格式错误的输入,然后回到正确的行,这可能已经滚动到那时,并打印正确格式化的值。
因此,你需要比scanf
更好的东西,它能够阻止 RETURN(和ENTER和长行)滚动屏幕,你需要terminfo
或等价物获得所需的控制序列,例如&#34;擦除此行&#34;和&#34;将光标移动到这一点&#34;。
scanf
无法替代强大的解析器。它是围绕阅读输入文件而设计的,对终端输入并不是很聪明。
答案 1 :(得分:1)
这将根据需要首先打印总和,但会以相反的顺序打印输入的 Dollars 。 到目前为止,未指定美元输入订单和打印订单。
检测\n
的问题远远低于。
使用货币变量推荐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.2lf\t\t\t\t\t%3.2lf\n", *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.2lf\t\t\t\t\t%3.2lf\n", numDollar, numShekel);
}
int main() {
double sumDollar = 0.0;
double sumShekel = 0.0;
double rate;
//...
printf("\n$\t\t\t\t\tIS\n");
GetMoney(rate, &sumDollar, &sumShekel);
//...
}
-
关于 money ,在这种情况下,具有$ 0.005等小数部分的值会导致问题。各种方法,一切都是最低的法律单位,如$ 0.01 - &gt; 1和$ 1.00 - &gt; 100 OR 轮计算:
sumDollar = round((sumDollar + numDollar)*100)/100;
numShekel = round((numDollar * rate)*100)/100;
如何最佳处理资金的问题超出了本文的范围。这只是一个存在特殊财务计算问题的FYI。
使用'\n'
(和'\n'
)读取一行用空格(scanf()
除外)然后最终以ungetc()
结尾的数字行,但不能值得编码,除非使用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
跟随一个数字,上面会被愚弄。
答案 2 :(得分:0)
scanf()如果成功返回读取的字符总数,否则返回负数。所以可以检查,
scanf(...)>0 or scanf(...)!=-1
条件。
scanf()需要cntrl + D,它会对待&#39; \ n&#39;作为其他空格,以便enter
使用fgets()
结束阅读输入。然后,您可以使用atof()
或strtof()