3

I successfully wrote this program that outputs a report in the terminal.

Though, when I attempt to print the same report to a disk file, I can't seem to figure out how to preserve the 'while' loop and get all the report out to print to disk file.

I've tried a couple of things like removing the 'header' function and placing that syntax in the 'summary' function along with all the necessary 'fprintf' statements in there. The outcome of this is just one line appearing in disk file output. Here is the transactiondata.txt file:

IMPORT     -25.19
EXPORT      35.41
EXPORT     100.25
IMPORT    -500.34
EXPORT     240.35
IMPORT    -134.56
EXPORT     459.56

How should I structure the code so that I get the same output that appears in the terminal window in a disk file?

The disk file output should look like this

The MoneyMaking Corporation
550 Warm Sands Drive
Palm Springs, CA 92262

Type            Amount              Net
----            ------              ---
IMPORT          -25.19            -25.19
EXPORT           35.41             10.22
EXPORT          100.25            110.47
IMPORT         -500.34           -389.97
EXPORT          240.35           -149.52
IMPORT         -134.56           -284.08
EXPORT          459.56            175.48

The net total for the month is $174.48
Transactions processed: 7

This is my code:

//C Libraries
#include <stdio.h>
#include <math.h>

//Global Variable Declarations

FILE *datafile;                  //disk file (for input)
FILE *reportfile;                // report file (for output)
char type [7];                   //Transaction Type: either IMPORT or EXPORt

float amount;                     //Transaction Amount
float absamount;                  //abs amount
float total;                      //Total
float runningsum;                 // End net balance at end of every transaction
int count;                        //Count of transactions

// Function Prototypes

void header (void);
void process (void);
void summary (void);

//*************************************************
//*************************************************
// M A I N   F U N C T I O N
//*************************************************
//*************************************************


int main (void){
// Initialize accumulating variables
    datafile = fopen("c:\\class\\mod5\\examples\\transactiondata.txt","r");   // Open input file
    count = 0;
    total = 0.00;
    runningsum = 0.00;

// Produce Report

   header();
   process();
   summary();

   fclose(datafile);
   system("pause");
   return 0;

}

// *************************************************************
// Header - prints a header on the report
// *************************************************************

void header (void)
{
    printf("The MoneyMaking Corporation\n");
    printf("550 Warm Sands Drive\n");
    printf("Palm Springs, CA 92262\n\n");

    printf("Type            Amount              Net\n");
    printf("----            ------              ---\n");
}

// *************************************************************
// Process - produces the detail lines of the report
// *************************************************************


void process (void)
{
    while(!feof(datafile))
    {
        fgets(type, 7, datafile);
        fscanf(datafile,"%f\n", &amount);
        absamount = fabs(amount);
        runningsum = amount + runningsum;
        printf("%s %15.2f %17.2f\n",type,absamount,runningsum);

    count++;              // You could also use count = count + 1
    total = total + amount;
    }


}

// *************************************************************
// Summary - prints the report summary (including accumulators)
// *************************************************************

void summary (void)
{
    // Local Variables

    float net;  //net values


    printf("\nThe net total for the month is $%1.2f\nTransactions processed: %d\n", total, count);

}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
davidw
  • 45
  • 7
  • 2
    What have you tried? For instance, if you realise that `printf(format,...);` is identical to `fprintf(stdout, format, ...);` you can make the file handle an argument to your functions, eg `void process(FILE *outfile) {...}`. BTW, [`while(!feof())` is almost always wrong](https://stackoverflow.com/q/5431941/1270789). – Ken Y-N Oct 30 '17 at 04:13
  • Hi @KenY-N, I've tried this: void summary (void) { reportfile = fopen("c:\\class\\mod5\\examples\\eweinrot_ie.txt","w"); fprintf(reportfile,"The...\n"); fprintf(reportfile,"550...\n"); fprintf(reportfile,"Palm...\n\n"); fprintf(reportfile,"Type Amount Net\n"); fprintf(reportfile,"---- ------ ---\n"); fprintf(reportfile,"%s %15.2f %17.2f\n",type,absamount,runningsum); fprintf(reportfile,"\nThe net total for the month is $%1.2f\nTransactions processed: %d\n", total, count); fclose(reportfile); } – davidw Oct 30 '17 at 04:17
  • don't use a floating-point for monetary values. And avoid `float` unless you really understand you need it. Use `double` instead – phuclv Oct 30 '17 at 04:32
  • What you need, in part, is functions like `void header(FILE *fp) { fprintf(fp, "The MoneyMaking Corporation\n"); … }` where you can call `header(stdout)` to write to standard output (the terminal), and `header(fp)` to write to the file stream identified by `FILE *fp`, which you open and close in `main()`. You can make that a file or whatever else you like. You need similar changes in `process()` and `summary()`. This is basically just a rehash of what Ken Y-N told you in his comment. – Jonathan Leffler Oct 30 '17 at 04:39
  • 2
    Well, then you need to hit your books hard! Now! What don't you understand? Function arguments? How to change `printf(` to `fprintf(fp,` in your editor? I included the syntax changes you need in the functions in the example — look at how I rewrote the signature and first line of `header()`. You do the equivalent changes in the other functions. You seem to know how to open a file with `fopen()`; you just need to capture the file stream (`FILE *` value) returned, and then pass that to your functions. It is really trivial. You need to modify the function declarations too, of course. – Jonathan Leffler Oct 30 '17 at 04:50
  • @JonathanLeffler, No. I can handle changing 'printf' to fprintf but I'm having a hard time understanding. I appreciate your patience and assistance. – davidw Oct 30 '17 at 04:54
  • Use back-quotes around code in comments. ```…like these `…``` And you can edit a comment for 5 minutes, so you can fix `
    ` and `
    ` to one backtick each (or two or three; just be self-consistent).
    – Jonathan Leffler Oct 30 '17 at 04:55
  • What is causing trouble? I'm not going to fix your code for you; that's your job. So the question is: what don't you understand about what you need to do? Your earlier [comment](https://stackoverflow.com/questions/47007980/fprintf-and-looping-in-c?noredirect=1#comment80962688_47007980) showed: `void summary (void) { reportfile = fopen("c:\\class\\mod5\\examples\\eweinrot_ie.txt","w");…`. You didn't self-evidently define `reportfile` in the function, so it is presumably a global variable `FILE *reportfile;`. All you need to do is write the code in `main()`, and then pass `reportfile` around. – Jonathan Leffler Oct 30 '17 at 04:59
  • @JonathanLeffler. Check me out...thanks for your guidance. :-) `int main (void){ // Initialize accumulating variables datafile = fopen("c:\\class\\mod5\\examples\\transactiondata.txt","r"); // Open input file reportfile = fopen("c:\\class\\mod5\\examples\\eweinrot_ie.txt","w"); // Open disk file` – davidw Oct 30 '17 at 05:18

1 Answers1

0

use fprintf.

void process (void)
{
    FILE *of = fopen("O_File", "a"); // reportfile the report file I guess
    while(!feof(datafile))
    {
        fgets(type, 7, datafile);
        fscanf(datafile,"%f\n", &amount);
        absamount = fabs(amount);
        runningsum = amount + runningsum;
        fprintf(of, "%s %15.2f %17.2f\n",type,absamount,runningsum);
        fprintf(stdout, "%s %15.2f %17.2f\n",type,absamount,runningsum); // to print to console

    count++;              // You could also use count = count + 1
    total = total + amount;
    }
    fclose(of);

}

I should have been more attentive to say the least, my above logic is pretty much an inefficient code with multiple openings, would server better if fopen and fclose calls are moved to main(). and considering FILE *reportfile is global nothing much is required except changing fprintf calls to write using reportfile instead of of.

instead of using those fprintf calls open reopen close logic

this code

int ofd = open("O_File", O_RDWR|O_APPEND);
close(1);
close(2);
dup(ofd);
close(ofd);

before calling below code sequence

// Produce Report

   header();
   process();
   summary();

should serve the purpose,

man -a dup

P.S - pretty much linux code untested on other platforms.

asio_guy
  • 3,667
  • 2
  • 19
  • 35
  • There's the `header()` and `summary()` functions too — and having them each open the file would be bad — inefficient, at least. – Jonathan Leffler Oct 30 '17 at 05:19