问题描述:

I need to write a program which reads a list of integers using scanf() (no using arrays). The first number is the representative exchange rate, and all remaining numbers represents cash amounts in dollars. The program should print the cash amount in dollars in "$" column and print in the "IS" column the cash amounts in the other coin (dollar*rate). In addition, program should print the sum of each column.

#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;

}

I have some questions:

  1. Based on the above program:

    user enters "rate" -> press enter key -> "enter list of numbers" ->

    press enter key.

    The problem: I want to print the column headers ($ and IS) only

    AFTER the above flow (i.e only AFTER user entered a list of integers

    and pressed enter key).

    I can`t just do the printing after the while loop, because then the

    columns headers will be printed below the columns values which is

    wrong. This is because I am restricted to print the next integer

    during the while loop because scanf will lose the previous value

    once the next one is read (correct?!)...

    Is there any way to iterate through all the integers stored in scanf buffer? so I can print the headers

    and then the values in one shot?

  2. In the above program, it seems that after all the column values are

    printed, the sum of each column is not printed until CTRL+D is

    entered. How can I make the sum to be printed also with the column

    values in one shot? I tried to change the while condition to != '\n'

    but it does not work because I am dealing with float and not char.

you can assume the list of integers are entered in a single line.

Please assist.

Thanks


I did a few changes.

Now I am left only with the 2nd problem. How can I print the sum with the columns headers in 1 shot? I don`t want to press CTRL+D and only then have the sum printed. I want columns Headers + Column Values + Columns Sum to be printed in one shot.

#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;

}

网友答案:

What you want to do isn't possible with just scanf and printf and without using arrays. You'd need to take over the character-by-character input system, using something like the readline library or the terminfo library.

The fundamental problem is that scanf(' %f', ...) will scan until it reads a floating point value, discarding all whitespace until then. "Whitespace" here not only means spaces and tabs but line ends as well! So the user can type RETURN a few times, the number, RETURN a few more, the second number, and RETURN before your code even gets to it. Your code would then need to obliterate all this malformatted input, work its way back up to the proper line, which may well have scrolled away by then, and print the properly formatted values.

Thus you need something better than scanf which will be able to block RETURN (and ENTER and long lines) from scrolling the screen, and you need terminfo or equivalent to get the control sequences needed to do things like "erase this line" and "move cursor to this point".

scanf is no substitute for a robust parser, unfortunately. It's designed around reading input files and isn't very smart about terminal input.

网友答案:
  1. This will print the sum first as desired, but will print the entered Dollars in reverse order.
    So far, dollar input order and printing order not specified.

  2. A kludge to detect \n is far below.

Recommend double with money variables.

Always check scanf() results. E.g. EOF, 0, 1

Space not needed in 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);
  //...
}

--

Concerning money, values in this case, that have fractional parts like $0.005 cause issues. Various approaches, do everything is the lowest legal unit like $0.01 --> 1 and $1.00 --> 100 OR round computation:

 sumDollar = round((sumDollar + numDollar)*100)/100;
 numShekel = round((numDollar * rate)*100)/100;

The issue of how to best handle money is beyond the scope of this post. This is just an FYI that there exist special financial computation issues.


Reading a line of numbers spaced with white-space (except '\n') and then finally terminated with '\n' is possible with scanf() (and ungetc()), but not worthy of coding except as an exercise as using fgets() and sscanf()/strtod() is far better. But fgets() uses a char array, banned by the post.

The below somewhat works, but is not robust:

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

The above gets fooled if a space and \n follow a number.

网友答案:

scanf() if successful returns the total number of characters read, otherwise a negative number is returned. so can check,

scanf(...)>0 or scanf(...)!=-1

condition.
scanf() needs cntrl+D, it treats '\n' as other white spaces so to end reading input on enter use fgets(). you can then convert the string to float using atof() or strtof()

相关阅读:
Top