有没有办法保持所有scanf

时间:2014-04-09 16:07:44

标签: c scanf

我需要编写一个程序,使用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;
}

我有一些问题:

  1. 基于以上计划:

    用户输入&#34; rate&#34; - &GT;按回车键 - &gt; &#34;输入数字列表&#34; - &GT; 按回车键。

    问题:我只想打印列标题($和IS) 在上述流程之后(即仅在用户输入整数列表之后) 并按下回车键)。

    我不能在while循环之后进行打印,因为那时候 列标题将打印在列值的下方 错误。这是因为我被限制打印下一个整数 在while循环期间,因为scanf将丢失先前的值 一读完下一个(正确吗?!)......

    有没有办法遍历存储在scanf缓冲区中的所有整数?所以我可以打印标题 然后是一次拍摄的价值?

  2. 在上面的程序中,似乎在所有列值之后 打印后,每栏的总和不会打印,直到CTRL + D为止 进入。如何使用列也可以打印总和 一次拍摄的价值?我试图将while条件改为!=&#39; \ n&#39; 但它不起作用,因为我处理浮动而不是char。

  3. 您可以假设整数列表输入一行。

    请协助。

    由于


    我做了一些改变。

    现在我只剩下第二个问题了。如何在一次打印中使用列标题打印总和?我不想按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;
    }
    

3 个答案:

答案 0 :(得分:2)

仅使用scanfprintf并且不使用数组,您想要做的事情是不可能的。您需要使用readline库或terminfo库之类的东西来接管逐个字符的输入系统。

基本问题是scanf(' %f', ...)将扫描直到它读取浮点值,直到那时丢弃所有空格。 &#34;空白&#34;这里不仅意味着空格和标签,还包括线端!因此,用户可以在代码进入之前输入RETURN几次,数字,RETURN几个,第二个数字和RETURN。然后你的代码需要删除所有这些格式错误的输入,然后回到正确的行,这可能已经滚动到那时,并打印正确格式化的值。

因此,你需要比scanf更好的东西,它能够阻止 RETURN(和ENTER和长行)滚动屏幕,你需要terminfo或等价物获得所需的控制序列,例如&#34;擦除此行&#34;和&#34;将光标移动到这一点&#34;。

遗憾的是,

scanf无法替代强大的解析器。它是围绕阅读输入文件而设计的,对终端输入并不是很聪明。

答案 1 :(得分:1)

  1. 这将根据需要首先打印总和,但会以相反的顺序打印输入的 Dollars 。 到目前为止,未指定美元输入订单和打印订单。

  2. 检测\n的问题远远低于。

  3. 使用货币变量推荐double

    始终检查scanf()结果。例如。 EOF01

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

将字符串转换为浮动