Need an inner loop to process lines from a file that have the same account number abd I cant seem to make it work.
Here is the scenario:
a text file containing an ordered listing of names. I am using while (fgets( filler, 115, FilePtr)) to read
each line of the file, with each line being no longer than 115 characters. I have no problem to read the lines and assign the read values to appropiate char or int type variables. I am also using atof to change some of the read values to double type numbers, so that they can be added as subtotals.
But what I want to do is to process a subset of the file, so that each time the account number changes, I can write the subtotals of each account number to a another file, and this is the part that I am hung up on. I have tried various if statements, while loops etc but I cant seem to get the right algorithm.
I still want to process the entire file, I just need a way to process each subset of data within the file.
Thanks
C
Last Comment
Kent Olsen
8/22/2022 - Mon
Kent Olsen
Hi ghp7000,
Odd seeing you in the C forum. :)
It's not too bad to do....
FILE *f;
char Buffer[116];
int Account = 0; // presumes that an account number of zero is invalid
int NewAcct;
f = fopen ();
while (fgets (Buffer, 115, f) > 0)
{
NewAcct = atoi (Buffer); // Convert as your data requires
if (NewAcct != Account) // change accounts
if (Account != 0) // Print totals if not the first time throuth the loop
{
PrintTotals ();
// Zero out the accumulators
}
// Add to the accululators
}
if (Account) // If any accounts were processed, there is still data in the accumulators for the last account
PrintTotals ();
That should just about do it.
Good Luck,
Kent
ghp7000
ASKER
lol, Im all over the place (one of the advantages of having unlimited points).
I will try your suggestion and let you know the outcome, this cant be as difficult as Im making it
Infinity08
Can you also show a sample of the text file, as well as which subset you'd like to get ... just an example to give us an idea ...
Well, C doesn't have DB2's cube functionality built in so it is a bit more work. ;)
ghp7000
ASKER
Sorry, Im still hung up. I am going to paste the entire function so that youc an see what Im doing:
/*****************************************************************************/
/*read_accounts */
/*****************************************************************************/
/*parses accounts.txt file */
int read_accounts(char * datafile, char * logfile, char * reportfile)
{
if(!OpenFiles(datafile, logfile, reportfile))
return(0);
while(fgets(filler,115,FilePtr))
{
LINENO=LINENO+1;
getstr(acctnumber, filler, 00, 7);
getstr(acctname, filler, 07, 30);
trim_spaces(acctname);
getstr(acctyear, filler, 37, 4);
trim_spaces(acctyear);
strcpy(processloop, acctname);
getstr(acctinvbalance, filler,100, 9);
trim_spaces(acctinvbalance);
if (strlen(acctinvbalance)==0)
strcpy(acctinvbalance,"0.00");
if((account!=atoi(acctnumber)) && (strcmp(acctyear,current_year)==0))
header(3,acctname,acctnumber,acctinvbalance);
if(strcmp(acctyear,current_year)==0)
{
account=atoi(acctnumber);
printf("%s %f %f\n", acctname, invtotal, invtotalsubtotal);
invtotal=0.00;
invtotalsubtotal=0.00;
}
getstr(acctmonth, filler, 41, 2);
trim_spaces(acctmonth);
getstr(acctday, filler, 43, 2);
trim_spaces(acctday);
getstr(acctinvnumber, filler, 45, 5);
trim_spaces(acctinvnumber);
getstr(acctinvtotal, filler, 73, 9);
getstr(acctinvpayment, filler, 82, 10);
getstr(acctinvdiscount, filler, 92, 8);
getstr(acctinvbalance, filler,100, 9);
getstr(acctinvpayment, filler, 82, 10);
getstr(acctinvdiscount, filler, 92, 8);
getstr(acctinvbalance, filler,100, 9);
if(strcmp(acctyear,current_year)!=0)
{
fprintf(ErrLogPtr, "%6d \t%-7s\t%-30s \t%s-%s-%s %5s %9s %10s %8s %9s \n", LINENO, acctnumber, acctname, acctday, acctmonth, acctyear, acctinvnumber, acctinvtotal, acctinvpayment, acctinvdiscount, acctinvbalance);
continue;
}
else
fprintf(RptPtr, "%s-%s-%s \t %5s \t %s \t %s \t %s \t %s \n", acctday, acctmonth, acctyear, acctinvnumber, acctinvtotal, acctinvpayment, acctinvdiscount, acctinvdiscount);
invtotal=atof(acctinvtotal);
invtotalsubtotal=invtotalsubtotal+invtotal;
}
if(!CloseFiles(datafile,logfile, reportfile))
return(0);
return(1);
}
the output prints the invtotal and invtotal subtotal for each line that meets the date qualification,what I want is to first:
be able to add each invoicetotal (ie keep track of running total per account number)
be able to print the result in the pointer file at the end of each account number listing.
Can you point out what I am doing wrong?
thanks for the reply.
I made some changes, the code now looks like this:
/*****************************************************************************/
/*read_accounts */
/*****************************************************************************/
/*parses accounts.txt file */
int read_accounts(char * datafile, char * logfile, char * reportfile)
{
if(!OpenFiles(datafile, logfile, reportfile))
return(0);
while(fgets(filler,115,FilePtr))
{
LINENO=LINENO+1;
getstr(acctnumber, filler, 00, 7);
getstr(acctname, filler, 07, 30);
trim_spaces(acctname);
getstr(acctyear, filler, 37, 4);
trim_spaces(acctyear);
strcpy(processloop, acctname);
getstr(acctinvbalance, filler,100, 9);
trim_spaces(acctinvbalance);
if (strlen(acctinvbalance)==0)
strcpy(acctinvbalance,"0.00");
if((account!=atoi(acctnumber)) && (strcmp(acctyear,current_year)==0))
{
header(3,acctname,acctnumber,acctinvbalance);
account=atoi(acctnumber);
fprintf(RptPtr,"%s %f %f\n", acctname, invtotal, invtotalsubtotal);
invtotal=0.00;
invtotalsubtotal=0.00;
}
getstr(acctmonth, filler, 41, 2);
trim_spaces(acctmonth);
getstr(acctday, filler, 43, 2);
trim_spaces(acctday);
getstr(acctinvnumber, filler, 45, 5);
trim_spaces(acctinvnumber);
getstr(acctinvtotal, filler, 73, 9);
getstr(acctinvpayment, filler, 82, 10);
getstr(acctinvdiscount, filler, 92, 8);
getstr(acctinvbalance, filler,100, 9);
getstr(acctinvpayment, filler, 82, 10);
getstr(acctinvdiscount, filler, 92, 8);
getstr(acctinvbalance, filler,100, 9);
if(strcmp(acctyear,current_year)!=0)
{
fprintf(ErrLogPtr, "%6d \t%-7s\t%-30s \t%s-%s-%s %5s %9s %10s %8s %9s \n", LINENO, acctnumber, acctname, acctday, acctmonth, acctyear, acctinvnumber, acctinvtotal, acctinvpayment, acctinvdiscount, acctinvbalance);
continue;
}
else
{
fprintf(RptPtr, "%s-%s-%s \t %5s \t %s \t %s \t %s \t %s \n", acctday, acctmonth, acctyear, acctinvnumber, acctinvtotal, acctinvpayment, acctinvdiscount, acctinvdiscount);
invtotal=atof(acctinvtotal);
invtotalsubtotal=invtotalsubtotal+invtotal;
}
}
if(!CloseFiles(datafile,logfile, reportfile))
return(0);
return(1);
}
but it gives this result:
****************************************************************************
ACCOUNTS RECEIEVABLE LIST
YEAR MONTH PERIOD: 2002/12
PREPARED ON : WEDNESDAY, MAY 30, 2007
****************************************************************************
first account number
CUSTOMER NAME :
CUSTOMER NUMBER: 0
OPENING BALANCE: 0.00
DATE INVOICE INVOICE PAYMENT
NUMBER AMOUNT AMOUNT
0.000000 0.000000>>>> this is fprintf of invtotal and subtotal, it should say 2208.00 and it should be printed after the detail list
24-10-2002 17872 2208.00
second account number
CUSTOMER NAME : CASH AND CARRY ACCT
CUSTOMER NUMBER: 1111111
OPENING BALANCE: 0.00
DATE INVOICE INVOICE PAYMENT
NUMBER AMOUNT AMOUNT
CASH AND CARRY ACCT (C.O.D)QC 2208.000000 2208.000000>>>this is the subtotal for first account
19-02-2002 16446 353.13
20-02-2002 16466 259.50
20-02-2002 -353.13 0.00 0.00
this is basically the same problem Ive had all along, I cant seem to find the right way to do this
Kent Olsen
Ah. Ok. :)
It's a little bit of a challenge to follow the code since there are no literals in it, but this should be close. Well, closer.....
sorry kdo, your code does exactly the same thing, it prints the subtotals before the detail lines:
here is the original code reposted with literals to help you debug this:
*****************************************************************************/
/*read_accounts */
/*****************************************************************************/
/*parses accounts.txt file */
int read_accounts(char * datafile, char * logfile, char * reportfile)
{
if(!OpenFiles(datafile, logfile, reportfile)) //test if can read/create/create files
return(0);
header(1,datafile,"", ""); //and write report header to error log ptr
header(2,reportfile,"",""); //and write report header to rpt ptr
message_box(8,datafile); //display processing file name to user
while(fgets(filler,115,FilePtr))
{
LINENO=LINENO+1;
getstr(acctnumber, filler, 00, 7); //all getstr read values from file
getstr(acctname, filler, 07, 30);
trim_spaces(acctname); //trim_spaces removes leading and trailing blanks
getstr(acctyear, filler, 37, 4);
trim_spaces(acctyear);
strcpy(processloop, acctname); //this is not used to do anything, should be removed!
getstr(acctinvbalance, filler,100, 9);
trim_spaces(acctinvbalance);
if (strlen(acctinvbalance)==0) //some values may contain only " . ", need to reset to 0.00
strcpy(acctinvbalance,"0.00");
if((account!=atoi(acctnumber)) && (strcmp(acctyear,current_year)==0))
{
header(3,acctname,acctnumber,acctinvbalance); //and write acct name, number and balance to rpt ptr
account=atoi(acctnumber); //process current account number
fprintf(RptPtr,"%s %f %f\n", acctname, invtotal, invtotalsubtotal);//write to rpt ptr but it is writing in the wrong place
invtotal=0.00; //reset the last amount to zero
invtotalsubtotal=0.00; //reset the running totals
}
getstr(acctmonth, filler, 41, 2);
trim_spaces(acctmonth);
getstr(acctday, filler, 43, 2);
trim_spaces(acctday);
getstr(acctinvnumber, filler, 45, 5);
trim_spaces(acctinvnumber);
getstr(acctinvtotal, filler, 73, 9);
getstr(acctinvpayment, filler, 82, 10);
getstr(acctinvdiscount, filler, 92, 8);
getstr(acctinvbalance, filler,100, 9);
getstr(acctinvpayment, filler, 82, 10);
getstr(acctinvdiscount, filler, 92, 8);
getstr(acctinvbalance, filler,100, 9);
if(strcmp(acctyear,current_year)!=0) //dont process any records if the year read from file is not the same as the year entered by the user to start the program
{
fprintf(ErrLogPtr, "%6d \t%-7s\t%-30s \t%s-%s-%s %5s %9s %10s %8s %9s \n", LINENO, acctnumber, acctname, acctday, acctmonth, acctyear, acctinvnumber, acctinvtotal, acctinvpayment, acctinvdiscount, acctinvbalance);//write all those records not prcoessed into the error log
continue;//go to next record in file
}
else //if the year is the same , write the detail line of each transaction to the rpt ptr file
{
fprintf(RptPtr, "%s-%s-%s \t %5s \t %s \t %s \t %s \t %s \n", acctday, acctmonth, acctyear, acctinvnumber, acctinvtotal, acctinvpayment, acctinvdiscount, acctinvdiscount);
invtotal=atof(acctinvtotal); //convert the string to float
invtotalsubtotal=invtotalsubtotal+invtotal; //keep the running total
}
}
if(!CloseFiles(datafile,logfile, reportfile)) //test if can close all files
return(0);
return(1);
}
if (strlen(acctinvbalance)==0) //some values may contain only " . ", need to reset to 0.00
strcpy(acctinvbalance,"0.00");
if((account!=atoi(acctnumber)) && (strcmp(acctyear,current_year)==0))
{
>> header(3,acctname,acctnumber,acctinvbalance); //and write acct name, number and balance to rpt ptr
account=atoi(acctnumber); //process current account number
>> fprintf(RptPtr,"%s %f %f\n", acctname, invtotal, invtotalsubtotal);//write to rpt ptr but it is writing in the wrong place
invtotal=0.00; //reset the last amount to zero
invtotalsubtotal=0.00; //reset the running totals
}
Swap the two lines marked with '>>'
You may also want to test whether this is "first pass" by testing that there is a saved account number. If not, you don't need to print empty totals.
whew.....
Kent
ghp7000
ASKER
sorry again, that didnt work, all it does is print the subtotals one line higher-what Im trying to do is print to the same file but at a different point in processing-first I want to print the detail lines and then print the subtotals-perhaps I need another approach? Maybe a linked list will do it the trick?
yes, the one function does all the printing, either by calling the header function or just doing the fprintf.
Okay, I will make the suggested change and inform you fo the result. Thanks again.
ghp7000
ASKER
yes, the account name, I didnt 'get it' right away, but that was the problem, thanks for helping me out
Odd seeing you in the C forum. :)
It's not too bad to do....
FILE *f;
char Buffer[116];
int Account = 0; // presumes that an account number of zero is invalid
int NewAcct;
f = fopen ();
while (fgets (Buffer, 115, f) > 0)
{
NewAcct = atoi (Buffer); // Convert as your data requires
if (NewAcct != Account) // change accounts
if (Account != 0) // Print totals if not the first time throuth the loop
{
PrintTotals ();
// Zero out the accumulators
}
// Add to the accululators
}
if (Account) // If any accounts were processed, there is still data in the accumulators for the last account
PrintTotals ();
That should just about do it.
Good Luck,
Kent