Solved

Input/Output / Array

Posted on 2004-08-15
18
477 Views
Last Modified: 2010-04-15
I am trying to read a file with currency conversion rates into the array in my program. At this point, I have come up with the following; however, I don't know what I'm missing or should be looking for. This is an assignment so I would appreciate any suggestions as to where I should be rewriting or adding code. Thanks.

#include <stdio.h>
#include <stdlib.h>

/*function prototyping*/
float fnCalculateConversion(float[],float, int);

/*main program starts here*/
int main(void)
{
     /*define variables*/
     char c;
     FILE *fmr, *frt;
     int selectionNumbers;
     float CURRENCIES[5];
     float AMOUNT = 0.0;
     int i;
     int j;  
     
     fmr = fopen("myrates.dat", "r");
     
     /*check for file errors during opening*/
     if (fmr == NULL)
     
     {
           printf("Can't open file for input\n");
           exit(1); /*exit program*/
     }
     
     /*open file for output*/
        frt = fopen("results.txt", "w");
     {
           printf("Can't open file for output\n");
           exit(1); /*exit program*/
     }
     
      /*conversions equal to $1 US dollar respectively for argentina, canada,
     united kingdon, hong kong, japan*/
         
     /*program title*/
     printf("Welcome to the Currency Conversion Program\n");
     
     /*build menu*/
          printf("----------------------------------------\n\n");
          printf("Press [1] for Argentina Pesos\n\n");
          printf("Press [2] for Canada Dollar\n\n");
          printf("Press [3] for United Kingdom Pounds\n\n");
          printf("Press [4] for Hong Kong Dollars\n\n");
          printf("Press [5] for Japan Yen\n\n");
          Printf("Press [q] to Quit Program\n\n");
         
     do {
          /*ask for user input - currency to convert*/
          printf("Please enter selection number of currency to convert: ");
          scanf("%d", &selectionNumbers);
         
          } while (selectionNumbers >5 || selectionNumbers <1);
     {
          /*ask for user input - dollar amount*/
          printf("Enter dollar amount to convert:  ");
          scanf("%f", &AMOUNT);
     }          
 
 
          /* loop through and store the numbers into the array */
        while(!feof(fmr))
        {
             fscanf(fmr, "%f", &CURRENCIES[i]); i++;
      }
      
      fclose(fmr);
        fclose(frt);

       
      /*call function to calculate conversion*/    
        fnCalculateConversion(CURRENCIES, AMOUNT, selectionNumbers);


       
         
          printf("\nThank you for using the Currency Conversion Program\n");
          /*stop program */
         
         
                   
          getchar();
          return 0;
         
         
         

}
         
     /* function to calculate conversion depending on selection by user */
       float fnCalculateConversion(float CURRENCIES[], float AMOUNT, int selectionNumbers)

     {
               /* declare variables */
               float conversion;
               switch(selectionNumbers)
         
               {
                    /* switch-case statements */
                    case 1:
                         conversion = CURRENCIES[0] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f Argentina Pesos\n\n",conversion);
                         break;
                   
                    case 2:
                         conversion = CURRENCIES[1] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f Canada Dollars\n\n",conversion);
                         break;
                         
                    case 3:
                         conversion = CURRENCIES[2] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f United Kingdom Pounds\n\n",conversion);
                         break;
                         
                    case 4:
                         conversion = CURRENCIES[3] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f Hong Kong Dollars\n\n",conversion);
                         break;
                         
                    case 5:
                         conversion = CURRENCIES[4] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f Japan Yen\n\n",conversion);
                         break;
                         

               }
               
               /* returns calculation to user */
               return conversion;
               
     
     
     }    
0
Comment
Question by:contesa
  • 9
  • 5
  • 4
18 Comments
 
LVL 3

Expert Comment

by:CmdrRickHunter
ID: 11806770
what is not working?  There's a lot of code there =p
What is the format of the currency file?  The way you have it, it would need to be a whitespace delimited file containing just a bunch of floating point numbers like
1.2
1.3
0.5

or
1.2 1.3 0.5


does the program compile?  does it give wrong results?

one change I would make, the function that does the conversion both prints the conversion and returns it.  It might be more propper to just return the value.  This makes the function real simple:
 return CURRENCIES[selectionNumbers]*ammount;

then have main() print out the value.


You could also make a const char* array containing the names of the currencies.
const char*  currencyNames[] = {"Arginitinian Pesos", "Canadian Dollars" /* continue the list */ };

this makes your "build menu" section into an easy loop:
for (i = 0; i < 5; i++)
  printf ("Press [%i] for %s.\n", i, currencyNames[i]);

much shorter, and you can easily add more countries.

You can also use the same array to print out the country name when showing the converted value.  This removes the need for the ugly switch statement.
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 300 total points
ID: 11806920
One thing.When you fill your currencies array from the file,you do this:
>>
while(!feof(fmr))
       {
            fscanf(fmr, "%f", &CURRENCIES[i]); i++;
       }
<<

But i is not initialized and may contain some garbage value.
When you declare the variable i,put
int i=0;
0
 
LVL 9

Accepted Solution

by:
ankuratvb earned 300 total points
ID: 11806929
This part is not allowing your program to function properly.

>>
/*open file for output*/
       frt = fopen("results.txt", "w");
    {
         printf("Can't open file for output\n");
         exit(1); /*exit program*/
    }
<<

It should be:
       frt = fopen("results.txt", "w");
if (frt==NULL)
    {
         printf("Can't open file for output\n");
         exit(1); /*exit program*/
    }
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 11806959
Also,this code will read the last conversion value from the file twice.
>>
while(!feof(fmr))
       {
            fscanf(fmr, "%f", &CURRENCIES[i]); i++;
    }
<<

Change it to:

while(!fscanf(fmr, "%f", &CURRENCIES[i]))
       {
         i++;
       }
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 300 total points
ID: 11807026
For my last comment,

It should be:

while(fscanf(fmr, "%f", &CURRENCIES[i])==1)
       {
         i++;
      }

Since fscanf returns the number of fields successfully read in.

See:
http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_20392271.html

http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_20757212.html
0
 

Author Comment

by:contesa
ID: 11815625
Ankuratvb & CmdrRickHunter, thank you very much for your assistance.

I made all the changes and the program does work with few errors --  my menu now displays with [0] for Argentina Pesos. When entering [0] for that selection, nothing happens. It will work if I enter 1 thru 4 but not when I enter [0].  Why is that? Do I have to change the initialization of int i? Another question, if I press q prior to running one conversion, the program starts an endless loop. I have to run one conversion before 'q' will work.  One last question, there is nothing being written to my output file? I am willing to award additional points for these questions...just tell me what I have to do.  Thanks again for your help. CmdrRickHunter, I used your idea of char *currencyNames to build the dynamic menu. I'm a little unsure of how to use it for the switch statements. I'm going to keep trying.

Thanks again

/contesa
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 300 total points
ID: 11817346
Nothing is being written to the file because you are not writing anything to the file.
You can use fprintf() to write to the file.Just as printf() writes output to the screen,fprintf() writes to file.

Your swtich-case defines cases from 1 to 5.If you want your program to run from 0 to 4,change the case statements.
Once you define a case for 0,it'll work fine.

q is a character and you scanf an integer,thats why its not working.
Do this:

do {
         /*ask for user input - currency to convert*/
         printf("Please enter selection number of currency to convert: ");
         scanf("%c", &selectionNumbers);
         if(selectionNumbers=='q') exit(0);
              else selectionNumbers-=48;
         } while (selectionNumbers >5 || selectionNumbers <1);
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 11817371
If you're using an array for currencynames as well,it'll eliminate the need for the switch-case;

You can simply do something like:

      float fnCalculateConversion(float CURRENCIES[], char *currencynames[],float AMOUNT, int selectionNumbers)

    {
              /* declare variables */
              float conversion;
              conversion = CURRENCIES[selectionNumbers-1] * AMOUNT;
              printf("\nYour U.S. Dollars equal $%.2f %s\n\n",conversion,currencynames[selectionNumbers-1]);

    }

Since corresponding indices of the arrays currencies and their names would be for the same currency,you can directly index into the array to do the calc. and the printing without using switch-case or if-else.
0
 
LVL 3

Assisted Solution

by:CmdrRickHunter
CmdrRickHunter earned 200 total points
ID: 11823836
If [0] is unusual for you, you can always do this:
printf("Press [%i] for %s", i + 1, currencyNames[i]);

and then, after scanf()ing the requested number, do AMMOUNT-- to change amount from a value from 1-5 to a value from 0 to 4.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 3

Assisted Solution

by:CmdrRickHunter
CmdrRickHunter earned 200 total points
ID: 11823899
oh, one more thing... just to explain a bit about ankuratvb's magic line:
selectionNumbers -= 48;

when you do a scanf("%c"), you got the number '0' as the character '0', which has the ascii value of 48 (ASCII is just a way of encoding letters into numbers).  when you subtract 48 from selectionNumbers, '1' becomes 1, '2' becomes 2, etc.  Whoever made ascii was really smart that way =)

a more common, and readable form is this;
selectionNumbers -= '0';
yes, that is a '0' within quotes (the ASCII code for the numeral 0).  C will then convert this into the ascii value (which is 48), and do the exact same thing.

Advantages: 1) this is how you see it in most programs   2) if you're on some obscure compiler that doesn't want to use ascii, you dont get screwed over, it will do the conversion properly (well, mostly properly)
0
 

Author Comment

by:contesa
ID: 11827275
Hi again...thank you again for all of your help...

I made the above changes. The program is running but there are some issues which I can't figure out. If I press a selection other than the ones listed, I get a repeated call for a selection number. When I tried using fprintf to output to my text file, the statement doesn't appear on the screen nor does it appear on my output file. I need suggestions on how to make it appear on my screen as well as my output file. By the way, although I wanted to change my switch statement--I can't--have to show all the concepts learned so far. So I have to leave it in...


#include <stdio.h>
#include <stdlib.h>

/*function prototyping*/
float fnCalculateConversion(float[],float, int);

/*main program starts here*/
int main(void)
{
     /*define variables*/
     char c;
     char *currencyNames[]={"Argentina_Pesos", "Canada_Dollars", "United_Kingdom_Pounds", "Hong_Kong_Dollars", "Japan_Yen"};
     FILE *fmr, *frt;
     int selectionNumbers;
     float CURRENCIES[5];
     float AMOUNT = 0.0;
     int i=0;
     
     /*open file for currency rates*/
     fmr = fopen("myrates.dat", "r");
     if (fmr == NULL)
     
     {
           printf("Can't open file for input\n");
           exit(1); /*exit program*/
     }
     
     /*open file for output*/
        frt = fopen("results.txt", "w");
      if (frt==NULL)
          {
               printf("Can't open file for output\n");
               exit(1); /*exit program*/
          }

     
           while(fscanf(fmr, "%f", &CURRENCIES[i])==1)
       {
         i++;
      }


     
     /*conversions equal to $1 US dollar respectively for argentina, canada,
     united kingdon, hong kong, japan*/
         
     /*program title*/
     printf("Welcome to the Currency Conversion Program\n");
     
     /*build menu*/
          printf("----------------------------------------\n\n");
     
          for (i = 0; i < 5; i++)
          printf ("Press [%i] for %s\n\n", i + 1, currencyNames[i]);


          Printf("Press [q] to Quit Program\n\n");
         
     do {
         /*ask for user input - currency to convert*/
         printf("Please enter selection number of currency to convert: ");
         scanf("%c", &selectionNumbers);
         if(selectionNumbers=='q') exit(0);
              else selectionNumbers-='0';
       
         } while (selectionNumbers >5 || selectionNumbers <1);

     {
          /*ask for user input - dollar amount*/
          printf("Enter dollar amount to convert:  ");
          scanf("%f", &AMOUNT);
     }          
 
          
          /*call function to calculate conversion*/    
          fnCalculateConversion(CURRENCIES, AMOUNT, selectionNumbers);
         
         

         
          printf("\nThank you for using the Currency Conversion Program\n");
          /*stop program */
         
         
         
          fclose(fmr);
          fclose(frt);
          getchar();
          return 0;
         
         
         

}
         
     /* function to calculate conversion depending on selection by user */
       float fnCalculateConversion(float CURRENCIES[], float AMOUNT, int selectionNumbers)
   {
               /* declare variables */
               float conversion;
               switch(selectionNumbers)
         
               {
                    /* switch-case statements */
                    case 1:
                         conversion = CURRENCIES[0] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f Argentina Pesos\n\n",conversion);
                         break;
                   
                    case 2:
                         conversion = CURRENCIES[1] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f Canada Dollars\n\n",conversion);
                         break;
                         
                    case 3:
                         conversion = CURRENCIES[2] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f United Kingdom Pounds\n\n",conversion);
                         break;
                         
                    case 4:
                         conversion = CURRENCIES[3] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f Hong Kong Dollars\n\n",conversion);
                         break;
                         
                    case 5:
                         conversion = CURRENCIES[4] * AMOUNT;
                         printf("\nYour U.S. Dollars equal $%.2f Japan Yen\n\n",conversion);
                         break;
                         

               }
               
               /* returns calculation to user */
               return conversion;
               
     
     
     }    


-------------------

Again, thank you for the help and explanations they have helped.

/contesa
       
0
 
LVL 3

Assisted Solution

by:CmdrRickHunter
CmdrRickHunter earned 200 total points
ID: 11833026
I'm a bit confused.  You want the output file to have the "invalid selection" message AND have it on the screen?  Two commands, do one printf, and one fprintf.

As for why it didn't appear in the file, you'll have to include the code that actually prints it.  I don't see any fprintf()s lying around in that code, so I'm assuming you pasted in a copy of the code without them.

One possibility: your two file names, frt and fmr are really close.  Its possible that you tried to output to the file with the currency data (which wouldn't actually write because you opened it in read mode).  I would sugest using more descriptive names

And last, just a snide comment (I know, unprofessionall, but hey, I'm not a professional, I'm an expert ;-) ): dont'cha just love it how professors want to "see what you've learned", even when there's a better way to do it? =p
0
 

Author Comment

by:contesa
ID: 11833392
Hi CmdrRickHunter,

Thank you again...I will give it another go.  And, by the way, I agree with you...if there's an easier way then why make it so hard for us--and I'm neither an expert or a professional!  LOL!!!

Thanks again...
0
 

Author Comment

by:contesa
ID: 11848700
One last question,

...........

fprintf(fresults, "\nThank you for using the Currency Conversion Program\n");
          printf("\nThank you for using the Currency Conversion Program\n");
         
.........

The above fprintf statement does work. However, what I need sent to the myresults file is the conversion statement. When I include the fprintf statement in the switch statements like so:

fprintf(fresults,"\nYour U.S. Dollars equal $%.2f Argentina Pesos\n\n",conversion);

it does not work because it doesn't recognize fresults as a variable. Why do I have to redeclare that variable? Thought I already declared it at the beginning of the program inside the main function. Does this mean that even though it's inside the main function, it is only local to that function? Or is it because I can't use fprintf inside switch statements. I have been researching switch statements and haven't come across an example using fprintf.

0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 11850817
Since fresults is defined in main(),it is accessible in main() only.
If you want to write to the file in the function fncalculateconversion(),pass the FILE *object variable to the function.

e.g.
float fnCalculateConversion(float CURRENCIES[], float AMOUNT, int selectionNumbers,FILE *fresults)

and do :
fprintf(fresults,"\nYour U.S. Dollars equal $%.2f Argentina Pesos\n\n",conversion);

in this function.

You'd call this function as:

FILE *frt;
frt = fopen("results.txt", "w");
if (frt==NULL)
       {
            printf("Can't open file for output\n");
            exit(1); /*exit program*/
       }
.
.
.
fnCalculateConversion(CURRENCIES, AMOUNT, selectionNumbers,frt);
.
.
.
fclose(frt);

Another,not so good way to do this is to define the FILE *frt variable globally i.e.before main().Then,it'd be accessible to all functions.
0
 

Author Comment

by:contesa
ID: 11852336
I'm getting the following error:  line 98: bad type in function fnCalculateConversion
'float fnCalculateConversion(float CURRENCIES[], float AMOUNT, int selectionNumbers, FILE *fresults) { float conversion'
aborting compile

I've tried everything I know possible...which unfortunately is not much...I'm throwing up my hands.  I also noticed that if I enter an invalid number as my first input, it recognizes that its wrong and then repeats enter currency selection three times. Then I can't get it out of the loop--no matter what number I put in....but that's another matter....more importantly, I need to get the output to work.  

Once again, thank you for your instructions and suggestions.


......................
/*function prototyping*/
float fnCalculateConversion(float[],float, int, FILE);

 /*open file for output*/
        fresults = fopen("results.txt", "w");
     if (fresults==NULL)
         {
              printf("Can't open file for output\n");
              exit(1); /*exit program*/
         }


 /*call function to calculate conversion*/    
          fnCalculateConversion(CURRENCIES, AMOUNT, selectionNumbers, fresults);

/* function to calculate conversion depending on selection by user */
       float fnCalculateConversion(float CURRENCIES[], float AMOUNT, int selectionNumbers, FILE *fresults)
   {
               /* declare variables */
               float conversion;
               switch(selectionNumbers)
         
               {
..............
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 300 total points
ID: 11853578
Your function declaration is:
float fnCalculateConversion(float[],float, int, FILE);

Should be:

float fnCalculateConversion(float[],float, int, FILE *);
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 300 total points
ID: 11853923
Not the best solution for your scanf invalid choice problem but you can use fflush(stdin) to clear the input buffer.

do {
        /*ask for user input - currency to convert*/
        printf("Please enter selection number of currency to convert: ");
        fflush(stdin);//flush stdin
        scanf("%c", &selectionNumbers);
        if(selectionNumbers=='q') exit(0);
             else selectionNumbers-='0';
       
        } while (selectionNumbers >5 || selectionNumbers <1);

At the same time,i should warn you that according to ANSI or the C standard,fflushing an input stream invokes undefined behaviour.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now