-
Trouble with a lab
Hi :)
I've been perusing the board here for a couple weeks, and have found it to be a great resource in learning C and C#. However, I can't find any answer to my current problem, which is part of a college homework assignment.
Here's my code so far:
Code:
/************************
* CIS 15AG AM - Lab VII
*
* A program to help a business keep
* statistics of its employee salaries
* for one year.
*
* Author: Michael Baird
*
* Begin date: Nov 28, 2005
* Last modified: Dec 4, 2005
**/
#include <stdio.h>
char PromptUser();
int CountEmployees();
void HighestAnnualSalary();
int main()
{
char choice;
do
{
choice = PromptUser();
switch( tolower( choice ) )
{
case 'c':
{
printf( "There are entries for %d employees.\n\n", CountEmployees() );
} break;
case 'h':
{
HighestAnnualSalary();
} break;
}
} while( tolower( choice ) != 'q' );//(choice = tolower( PromptUser() )) != 'q' );
system( "PAUSE" );
return 0;
}
char PromptUser()
{
char res;
printf( "Choose an option from the following menu:\n" );
printf( "\tc: calculate total employees\n" );
printf( "\th: report highest annual salary\n" );
printf( "\ta: calculate average monthly salary\n" );
printf( "\tf: format the report to output file\n" );
printf( "\tq: quit this application\n\n" );
printf( "Enter your choice: " );
scanf( " %c", &res );
return res;
}
int CountEmployees()
{
FILE * input;
int count = 0;
char holder;
if( (input = fopen( "lab7_input.txt", "r" )) == NULL )
{
printf( "Error opening input file.\n" );
return 1;
}
while( (fscanf( input, "%c", &holder ) != EOF) )
{
if( holder == '\n' )
count++;
}
fclose( input );
return count;
}
void HighestAnnualSalary()
{
}
I'm stuck at calculating the highest annual salaray. It's supposed to read from an input file without using strings, structs, or arrays. Here's an excerpt from the input file:
Code:
1234,12,1200 2050 3010 4000 5560 6005 6780 5340 4000.50 3040 2005 1100
The first int is the employee ID, and the second is the number of months the employee worked (the application is a business salary tracker). All the other numbers can be floats (but aren't in this example) and represent the amount earned in that month. So for example, January is at 1200, February at 2050, and December at 1100. I can't figure out how to pull those twelve floats out and do calculations without calculating the ID and the months worked as well.
If I need to clarify anything, please let me know.
-
fscanf seems the obvious choice. Read one int, the read one char to get rid of the comma, then read the second int, and read a char again to kill off the comma.
Then, read one and one float and put them whereever you like (I would declare a float array the size of the months, dunno if you are allowed that in your assignment).
-
Unfortunately, I'm not allowed to use arrays at all :/
Would your suggestion be like this (I apologize for not testing first, but I dont have an IDE at hand here):
Code:
fscanf( input, "%d%c%d%c%f...%f" );
?
-
You don't need an array because there is no need to store all the values, you just need to keep track of the max.
Code:
max = 0;
for each salary
if salary > max
max = salary
return max
you can read the first two values with two calls to fscanf like
Code:
fscanf( input, "%d,", &id );
fscanf( input, "%d,", &num_of_months );
then loop from 0 to < num_of months and read the salaries keeping track of the max as you go
Code:
loop num_of_month times
fscanf( input, "%f", &salary );
this only applies to a single line in the file. You'll need to do more to go through the entire file.
-
I see. So fscanf( ... ) doesn't go back to the start of the line if the call to the function ends? That's helpful info. Thanks, I'll get back to giving it a shot :)
-
Oh, of course, you don't need an array - silly me.
fscanf does not care for spaces if you ask it to read numbers, btw, so you would only need to read a char twice to kill the two commas.
-
Hrm. I've been battling this one again for a while. I dont understand why I'm so baffled by this, but I need support again. Here's what I have so far:
Code:
/************************
* CIS 15AG AM - Lab VII
*
* A program to help a business keep
* statistics of its employee salaries
* for one year.
*
* Author: Michael Baird
*
* Begin date: Nov 28, 2005
* Last modified: Dec 4, 2005
**/
#include <stdio.h>
char PromptUser();
int CountEmployees();
void HighestAnnualSalary();
int main()
{
char choice;
do
{
choice = PromptUser();
switch( tolower( choice ) )
{
case 'c':
{
printf( "There are entries for %d employees.\n\n", CountEmployees() );
} break;
case 'h':
{
HighestAnnualSalary();
} break;
}
} while( tolower( choice ) != 'q' );
system( "PAUSE" );
return 0;
}
char PromptUser()
{
char res;
printf( "Choose an option from the following menu:\n" );
printf( "\tc: calculate total employees\n" );
printf( "\th: report highest annual salary\n" );
printf( "\ta: calculate average monthly salary\n" );
printf( "\tf: format the report to output file\n" );
printf( "\tq: quit this application\n\n" );
printf( "Enter your choice: " );
scanf( " %c", &res );
return res;
}
int CountEmployees()
{
FILE * input;
int count = 0;
char holder;
if( (input = fopen( "lab7_input.txt", "r" )) == NULL )
{
printf( "Error opening input file.\n" );
return 1;
}
while( (fscanf( input, "%c", &holder ) != EOF) )
{
if( holder == '\n' )
count++;
}
fclose( input );
return count;
}
void HighestAnnualSalary()
{
FILE * input;
char holder;
int i, j;
int studentID, monthsWorked;
float salary = 0, highestSalary = 0;
if( (input = fopen( "lab7_input.txt", "r" )) == NULL )
{
printf( "Error opening input file.\n" );
return;
}
for( j = 0; j < CountEmployees(); j++ )
{
while( (fscanf( input, "%c", &holder ) != EOF) )
{
fscanf( input, "%d,", &studentID );
fscanf( input, "%d,", &monthsWorked );
for( i = 0; i < monthsWorked; i++ )
salary += fscanf( input, "%f", &salary );
if( salary > highestSalary )
highestSalary = salary;
}
}
printf( "Highest salary: %.2f\n\n", highestSalary );
}
And here's the input:
Code:
1234,12,1200 2050 3010 4000 5560 6005 6780 5340 4000.50 3040 2005 1100
2245,5,980 525 1120 405.50 650.50
3496,3, 1020.50 2085 1050.50
8849,10,500.50 305.50 810 925 1060 1256.50 800.50 810.50 1087 578
2390,6,875.50 1020 510.50 790 250.50 1000.50
When I select 'h', it tells me the highest salary is 1101.00, and I don't know why. As to the input file, the first two numbers are employee ID and months worked respectively. The rest is the monthly salary, and if they didnt work that month then there's a space. It's damn confusing if you ask me, but it's already overdue so I can't complain.
Any help would be greatly appreciated.
-
When fscanf successfully reads one value it will return 1, so you are adding 1 to salary each time.
Also, you are changing the value of salary before you compare/set it to highest, so you need a different variable to keep track of the total
for highest annual salary of all employees you'd want something like
Code:
for( j = 0; j < CountEmployees(); j++ )
{
while( (fscanf( input, "%c", &holder ) != EOF) )
{
fscanf( input, "%d,", &studentID );
fscanf( input, "%d,", &monthsWorked );
for( i = 0; i < monthsWorked; i++ )
{
fscanf( input, "%f", &salary );
total_salary += salary;
}
if( total_salary > highestSalary )
{
highestSalary = total_salary;
}
total_salary = 0; //reset for each employee
}
}
printf( "Highest salary: %.2f\n\n", highestSalary
);
-
fscanf() returns the number of items read and assigned, or EOF.
Thus, your line
Code:
salary += fscanf( input, "%f", &salary );
Does not do what you want. I am not sure what it does, but you'll get fantastic output.
try this:
Code:
for( i = 0; i < monthsWorked; i++ )
int ret = fscanf( input, "%f", &salary );
//ret will let you know if you got EOF, or if fscanf failed somehow.
//as before onwards - salary now contains the newly read number, so just check it vs. highestSalary.
-
Code:
salary += fscanf( input, "%f", &salary );
I think this was intended:
Code:
fscanf( input, "%f", &temp );
salary += temp;
-
tolower() and family are in <ctype.h>.
-
Thank you all so much. That's really helpful. I'm sure I'll be back with more questions (and I think I know why - after rereading the assignment, it's written very poorly, but my professor is a CIS major, not an English major), but thank you for all the help so far!
-
One final question, and it's to do with formatting this input file into an output file. Here's the code so far:
Code:
/************************
* CIS 15AG AM - Lab VII
*
* A program to help a business keep
* statistics of its employee salaries
* for one year.
*
* Author: Michael Baird
*
* Begin date: Nov 28, 2005
* Last modified: Dec 6, 2005
**/
#include <stdio.h>
#include <ctype.h>
char PromptUser();
int CountEmployees();
void HighestAnnualSalary();
float CalculateHighestSalary( int * emp );
void AverageMonthly();
float CalculateAverageSalary();
void FormatReport();
int InputToOutput();
int main()
{
char choice;
do
{
choice = PromptUser();
switch( tolower( choice ) )
{
case 'c':
{
printf( "There are entries for %d employees.\n\n", CountEmployees() );
} break;
case 'h':
{
HighestAnnualSalary();
} break;
case 'a':
{
AverageMonthly();
} break;
case 'f':
{
FormatReport();
} break;
}
} while( tolower( choice ) != 'q' );
system( "PAUSE" );
return 0;
}
char PromptUser()
{
char res;
printf( "Choose an option from the following menu:\n" );
printf( "\tc: calculate total employees\n" );
printf( "\th: report highest annual salary\n" );
printf( "\ta: calculate average monthly salary\n" );
printf( "\tf: format the report to output file\n" );
printf( "\tq: quit this application\n\n" );
printf( "Enter your choice: " );
scanf( " %c", &res );
return res;
}
int CountEmployees()
{
FILE * input;
int count = 0;
char holder;
if( (input = fopen( "lab7_input.txt", "r" )) == NULL )
{
printf( "Error opening input file.\n" );
return 1;
}
while( (fscanf( input, "%c", &holder ) != EOF) )
{
if( holder == '\n' )
count++;
}
fclose( input );
return count;
}
void HighestAnnualSalary()
{
int employee = 0;
float highest = CalculateHighestSalary( &employee );
printf( "Employee %d has the highest annual salary of %.2f.\n\n", employee, highest );
return;
}
float CalculateHighestSalary( int * emp )
{
FILE * input;
int i, j; //for use with loop methods
int employeeID, monthsWorked;
float highestSalary = 0, iSalary /*individual monthly salary*/ = 0, iTotalSalary = 0 /*individual total salary*/;
if( (input = fopen( "lab7_input.txt", "r" )) == NULL )
{
printf( "Error opening input file.\n" );
return 1;
}
for( j = 0; j < CountEmployees(); j++ )
{
while( fscanf( input, "%d,", &employeeID ) != EOF )
{
fscanf( input, "%d,", &monthsWorked );
for( i = 0; i < monthsWorked; i++ )
{
fscanf( input, "%f", &iSalary );
iTotalSalary += iSalary;
}
if( iTotalSalary > highestSalary )
{
highestSalary = iTotalSalary;
*emp = employeeID;
}
//reset for each employee
iSalary = 0;
iTotalSalary = 0;
}
}
fclose( input );
return highestSalary;
}
void AverageMonthly()
{
printf( "The average monthly salary for all employees is: %.2f.\n\n", CalculateAverageSalary() );
return;
}
float CalculateAverageSalary()
{
FILE * input;
int i, j; //for use with loop methods
int employeeID; //holder for this entry
int totalMonths = 0, iMonthsWorked /*individual months worked*/;
float totalAverage = 0, iSalary /*individual monthly salary*/;
if( (input = fopen( "lab7_input.txt", "r" )) == NULL )
{
printf( "Error opening the input file.\n" );
return 1;
}
for( j = 0; j < CountEmployees(); j++ )
{
while( fscanf( input, "%d,", &employeeID ) != EOF )
{
fscanf( input, "%d,", &iMonthsWorked );
totalMonths += iMonthsWorked;
for( i = 0; i < iMonthsWorked; i++ )
{
fscanf( input, "%f", &iSalary );
totalAverage += iSalary; //store in totalAverage simply to save mem space
}
}
}
return (totalAverage / totalMonths);
}
void FormatReport()
{
if( InputToOutput() )
{
printf( "The input file has been successfully written to the output file, \'out.txt\'.\n\n" );
}
else
printf( "Formatting failed.\n\n" );
return;
}
int InputToOutput()
{
FILE * input;
FILE * output;
int i, j; //for use with loops
int employeeID, monthsWorked;
float jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec;
if( (input = fopen( "lab7_input.txt", "r" )) == NULL )
{
printf( "Error opening input file.\n" );
return 0;
}
else if( (output = fopen( "out.txt", "w" )) == NULL )
{
printf( "Error creating output file.\n" );
return 0;
}
for( j = 0; j < CountEmployees(); j++ )
{
while( fscanf( input, "%d,", &employeeID ) != EOF )
{
fscanf( input, "%d,", &monthsWorked );
fprintf( output, "%d\t%d", employeeID, monthsWorked );
}
}
}
The two functions that are related to this question are the last two at the bottom there.
The input file is this:
Code:
1234,12,1200 2050 3010 4000 5560 6005 6780 5340 4000.50 3040 2005 1100
2245,5,980 525 1120 405.50 650.50
3496,3, 1020.50 2085 1050.50
8849,10,500.50 305.50 810 925 1060 1256.50 800.50 810.50 1087 578
2390,6,875.50 1020 510.50 790 250.50 1000.50
As I said above, the first two ints represent the ID and the number of months worked. The rest are floats reprsenting the monthly salary earned. If the employee didnt work for a certain month, there's a space (I know, damn confusing to try and look at and determine which months the employee worked/didnt work). For example, if the employee worked January and March, but not February, there's an extra space between the first and third floats. Hope that makes sense, cause it took me an hour to figure it out.
Anyway, here's my dilemma: I need to replace the "extra" spaces - those for unemployed months - with asteriks ( '*' ), while keeping the full float numbers in tact to also print those in between.
You can see in the last function of my code that I also output the ID and the months worked, separated by tabs. After that, it's supposed to be either the monthly income or an asterik if unemployed for the month.
I'll keep tinkering with what I've got above, but if I'm on the wrong track or if there are any great ideas (like all the ones above :)), please help!
-
Why don't you save yourself the trouble and write 0.0 to the file for when they don't work that month?
Quzah.
-
That'd be going against the rule of the lab, and in either case, I still don't know how to read a space versus an entire float (switching between %c or %f).