Finding Mean in C program - c

I need some advice or hints about how to calculate the average of insurance, tax, gross and net salary. Just need some enlightment.
Tried to add average function before but it seems that its hard to get the value from other function.
Any ideas? This code is used to find the salary of employee and its average.
char EmpName[50];
int EmpID, EmpAge, EmpNum, i;
float gross_salary, net_salary;
float insurance, tax, total, total_insurance, total_tax;
int main()
{
int i;
FILE *file;
file = fopen("UserDetails.txt", "wt");
printf("Number of Employee to process: ");
scanf("%d", &EmpNum);
i = 1;
EmployeeName: while( i <= EmpNum)
{
printf("\nEmployee name: "); scanf("%s", &EmpName);
if (strlen(EmpName) <= 50){
EmployeeID: printf("Employee ID: "); scanf("%d", &EmpID);
if (EmpID >= 1000 && EmpID <= 9999){
EmployeeAge: printf("Employee Age: "); scanf("%d", &EmpAge);
if (EmpAge >= 18 && EmpAge <= 99){
printf("Employee Salary: "); scanf("%g", &gross_salary);
if (gross_salary >= 0.0 && gross_salary <= 9999.99){
goto Total;
}
}
else{
printf("\nInvalid Input!\nEmployee Age Is Between 18 To 99\n");
goto EmployeeAge;
}
}
else{
printf("\nInvalid Input!\nEmployee ID Number is Between 1000 To 9999\n");
goto EmployeeID;
}
}
else{
printf("\nInvalid Input!\nMax Character is 50\n");
goto EmployeeName;
}
Total: printf("\n");
SetInsurance(EmpAge);
IncomeTax(gross_salary);
TaxDeduction(tax);
InsuranceDeduction(insurance);
NetSalary();
Average(insurance,gross_salary,net_salary);
i++;
fprintf(file, "Employee name: %s\n", EmpName); //print data inside file
fprintf(file, "Employee ID: %d\n", EmpID);
fprintf(file, "Employee Age: %d\n", EmpAge);
fprintf(file, "Employee Salary: %g\n\n", gross_salary);
}
fclose(file);
}
float SetInsurance(int x){
while (i <= EmpNum){
if (x <= 35)
insurance = 110;
else if (x >=36 && x <= 65)
insurance = 160;
else if (x > 65)
insurance = 250;
else
printf("Under Age!");
total = insurance;
printf("\nInsurance: %.2f\n", total);
return total;i++;
};
}
float IncomeTax(float salary) {
int i = 0;
while(i < EmpNum){
if (salary <= 999.99)
tax = 0;
else if (salary >= 1000 && salary <= 2999.99)
tax = 2.5;
else if (salary >= 3000)
tax = 5;
else
printf("Invalid Input!\n");
printf("Income Tax Rate: %.2f%\n", tax);
return tax;
i++;
}
}
float InsuranceDeduction(float insurance){
if (insurance == 110){
total_insurance =+ 110;
}else if (insurance == 160){
total_insurance =+ 160;
}else if (insurance == 250){
total_insurance =+ 250;
}
return total_insurance;
}
float TaxDeduction(float tax){
if(tax == 2.5){
total_tax = gross_salary * 0.025;
}else if(tax == 5){
total_tax = gross_salary * 0.05;
}
return total_tax;
}
void NetSalary(){
total = TaxDeduction(tax) + InsuranceDeduction(insurance);
net_salary = gross_salary - total;
printf("Net Salary: RM%.2f\n", net_salary);
}

I order to solve the problem you face, I'd follow the recomendations you have received from other responses, and in addition:
If you fopen() a file, just check that the returned pointer is valid, as you can have several errors derived of:
Not having permissions to read the file.
file doesn't exist.
and these should be handled before you start processing the file.
Second, You don't need to store the data from the file, except for error purposes (it's preferable if you say that Martina Navratilova cannot be paying such ridiculous amount of taxes than saying that record 6437 in the file has a ridiculous amount of taxes to be payd -- you should search for it by counting, while your program has already done it)
If I would to decide how the input file is formatted, I should make a two line record, one line to specify the user name (which so, can have spaces embedded, as the new line marks the end of the name) so it can be read with fgets(), and a second line with all the numeric data you are going to fscanf(), after the sequence is done, you have all the data for a single user. Another possibility (to allow the name with spaces) is to put the name as the last field of the data file, so you can read all the last field characters upto the \n as the user name. This would allow to put each user in one single line

"I need some advice or hints., ...,any idea?"
First: Read and act on each of suggestions in first 3 comments under your post from #Chux.
Other suggestions:
Avoid using goto tag ... :tag statements to traverse code.
Create functions that can be called to do a simple task, then return.
Use a struct to contain related data when there can be more that one related data set.
Change
char EmpName[50];
int EmpID, EmpAge, EmpNum, i;
float gross_salary, net_salary;
float insurance, tax, total, total_insurance, total_tax;
To for example: (Note, not all these members may be necessary, depending on how you finally implement the records needed for each employee.)
typedef struct {
char EmpName[50];
int EmpID;
int EmpAge;
double gross_salary;
double net_salary;
double insurance;
double total_insurance; //may not be necessary in struct
double tax;
double total_tax; //may not be necessary in struct
}account_s;
Note, if "total" members are to be used as totals for all employees, then they should probably not be a members in the struct.
Create instance(s) of this struct in local space, Eg.
int main(void)
{
int EmpNum = 0;
...
printf("Enter number of Employees to process: ");
scanf("%d", &EmpNum);
account_s account[EmpNum];//creates an array of instances of account_s
memset(account, 0, sizeof account);//initializes array
Incorporate account_s into functions as return type, and/or function parameters. Eg.
The following is a very brief, but compilable and runable example to illustrate several things including how to pass a single function argument containing all the information needed to update and contain employee information (via struct).
//prototypes
void populateAccounts(int count, account_s record[count]);
void SetInsurance(account_s *record);
double Get_ave_salery(int c, account_s *account);
int main(void)
{
int EmpNum = 0;
printf("Number of Employee to process: ");
scanf("%d", &EmpNum);
account_s account[EmpNum];//creates an array of instances of account_s
memset(account, 0, sizeof account);//initializes array
populateAccounts(EmpNum, account);
double ave_salary = Get_ave_salery(EmpNum, account);
printf("Average Gross Salary: %lf\n", ave_salary);
return 0;
}
void populateAccounts(int count, account_s record[count])
{
//Read in information for each account
for(int i=0; i<count; i++)
{
printf("\nEnter employee name: ");
scanf("%s", record[i].EmpName);
printf("\nEnter employee ID: ");
scanf("%d", &record[i].EmpID);
printf("\nEnter employee Age: ");
scanf("%d", &record[i].EmpAge);
printf("\nEnter employee Salary: ");
scanf("%lf", &record[i].gross_salary);
SetInsurance(&record[i]);//function to set insurance via function argument
// etc.
}
}
void SetInsurance(account_s * record){
if (record->EmpAge <= 35)
record->insurance = 110;
else if (record->EmpAge >=36 && record->EmpAge <= 65)
record->insurance = 160;
else if (record->EmpAge > 65)
record->insurance = 250;
else
printf("Under Age!");
// total = record->insurance;
printf("\nInsurance: %.2f\n", record->insurance);
}
double Get_ave_salery(int c, account_s *account)
{
double ave = 0.0;
double sum = 0.0;
for(int i=0; i<c; i++)
{
sum += account[i].gross_salary;
}
return sum/c;
}
There is more for you to do here, but this should help you to get started.

Related

Beginner in C: Can't properly printf first and last element in double array?

I'm trying to display a Wish List on the command line. The user enters the cost of the item, the level of priority (1-3), and whether or not it has financing options (y/n). The inputted values are put in multiple arrays. After the user enters all their values, they're displayed in a table at the end.
Everything in my code works fine except when I try to printf the user inputed cost values (double itemCosts[numOfItems];) in the table. The first and last element don't print properly, even when I input the same price (6225.88) for all of them. The last element is just 0.000000. See included pic of table output.
I tried debugging the issue by separating the cost-related loops and compiling/running them as another file and the costs display correctly...so I'm thinking the bug is somewhere else, but I can't find it.
#define MAX_ITEMS 10
#include <stdio.h>
int main()
{
const double MIN_INCOME = 500, MAX_INCOME = 400000;
int numOfItems;
double netIncome, itemTotal;
double itemCosts[numOfItems];
int itemPriors[numOfItems];
char itemFinOps[numOfItems];
printf("+--------------------------+\n");
printf("+ Wish List Forecaster |\n");
printf("+--------------------------+\n\n");
// Prompt for net monthly income
do
{
printf("Enter your monthly NET income: $");
scanf("%lf", &netIncome);
if (netIncome < MIN_INCOME)
{
printf("ERROR: You must have a consistent monthly income of at least $500.00\n\n");
}
else if (netIncome > MAX_INCOME)
{
printf("ERROR: Liar! I'll believe you if you enter a value no more than $400000.00\n\n");
}
} while (!(netIncome >= MIN_INCOME && netIncome <= MAX_INCOME));
printf("\n");
// Prompt for # of wish list items
do
{
printf("How many wish list items do you want to forecast?: ");
scanf("%d", &numOfItems);
if (!(numOfItems > 0 && numOfItems <= MAX_ITEMS))
{
printf("ERROR: List is restricted to between 1 and 10 items.\n\n");
}
printf("\n");
} while (!(numOfItems > 0 && numOfItems <= MAX_ITEMS));
// Store wish list item details
for (int i = 0; i < numOfItems; i++)
{
printf("Item-%d Details:\n", i + 1);
do //////////////// ******** PROMPT COST ********** //////////
{
printf("Item cost: $");
scanf("%lf", &itemCosts[i]);
if (!(itemCosts[i] >= (double)100))
{
printf(" ERROR: Cost must be at least $100.00\n");
}
} while (!(itemCosts[i] >= (double)100));
do // prompt priority
{
printf("How important is it to you? [1=must have, 2=important, 3=want]: ");
scanf("%d", &itemPriors[i]);
if (!(itemPriors[i] >= 1 && itemPriors[i] <= 3))
{
printf(" ERROR: Value must be between 1 and 3\n");
}
} while (!(itemPriors[i] >= 1 && itemPriors[i] <= 3));
do // prompt finance options
{
printf("Does this item have financing options? [y/n]: ");
scanf(" %c", &itemFinOps[i]);
if (!(itemFinOps[i] == 'y' || itemFinOps[i] == 'n'))
{
printf(" ERROR: Must be a lowercase 'y' or 'n'\n");
}
} while (!(itemFinOps[i] == 'y' || itemFinOps[i] == 'n'));
printf("\n");
}
///////// display summary of item details in TABLE //////////
printf("Item Priority Financed Cost\n");
printf("---- -------- -------- -----------\n");
for (int j = 0; j < numOfItems; j++)
{
printf(" %d %d %c %lf\n", j + 1, itemPriors[j], itemFinOps[j], itemCosts[j]);
itemTotal += itemCosts[j];
}
return 0;
}
int numOfItems;
double netIncome, itemTotal;
double itemCosts[numOfItems];
int itemPriors[numOfItems];
char itemFinOps[numOfItems];
It is undefined behaviour as your numOfItems is not inilized. In C table will not grow or shrink to the size when you change this variable
Change to:
double itemCosts[MAX_ITEMS];
int itemPriors[MAX_ITEM];
char itemFinOps[MAX_ITEM];
Always check the result of scanf. Exmaple:
if(scanf("%lf", &netIncome) != 1){ /* handle error*/}
As Vlad from Moscow and 0___________ said, you cannot define an array using a not initialised variable for the number of its elements. You can define the variables as
double *itemCosts;
int *itemPriors;
char *itemFinOps;
and after the variable numOfItems is given a value, you dynamically allocate memory as follows:
itemCosts = (double*) malloc(numOfItems * sizeof(double));
itemPriors = (int*) malloc(numOfItems * sizeof(int));
itemFinOps = (char*) malloc(numOfItems * sizeof(char));
or
itemCosts = (double*) calloc(numOfItems, sizeof(double));
itemPriors = (int*) calloc(numOfItems, sizeof(int));
itemFinOps = (char*) calloc(numOfItems, sizeof(char));
calloc initialises all elements of array to 0
At the end you must free the allocated memory:
free(itemCosts);
free(itemPriors);
free(itemFinOps);

Retrieving A Value From A Void Function

I was recently given an assignment by one of my professors in which I have to write a piece of code in which it prompts for a salary, years of service, and then based on those two pieces of info it calculates a bonus. I've worked with functions declared as doubles, but this is my first time working with void functions. I'm having trouble understanding how I can get my first function to save the prompted values for years of service and salary and then use those in the next function to calculate the bonus. This is what I currently have:
#include <cstdio>
void GetInput()
{
double salary;
int years_service;
printf("Enter your salary: ");
scanf("%lf", &salary);
printf("How many years have your served for us? ");
scanf("%d", &years_service);
}
void CalcRaise()
{
//I initialized salary and years_service because they would not compile
//otherwise. As expected, it does run but since they are set to 0, the
//bonus will be zero.
double salary = 0;
int years_service = 0;
double bonusA;
double bonusB;
double bonusC;
bonusA = salary * .02;
bonusB = salary * .05;
bonusC = salary * .10;
if ( years_service < 2)
{
printf("Here is your bonus: %lf", bonusA);
}
else if ( years_service > 5 && years_service < 10)
{
printf("Here is your bonus: %lf", bonusB);
}
else
{
printf("Here is your bonus: %lf", bonusC);
}
return;
}
int main()
{
GetInput();
CalcRaise();
return 0;
}
As I mentioned, I'm just having trouble figuring out how to save the values from my first function and use those to calculate the bonus. Any help is appreciated. -Thanks
Make all the variables global, and initialize those variables in the starting stage itself.
#include <stdio.h>
#include <stdlib.h>
double salary = 0;
int years_service = 0;
double bonusA;
double bonusB;
double bonusC;
void GetInput()
{
printf("Enter your salary: ");
scanf("%lf", &salary);
printf("How many years have your served for us? ");
scanf("%d", &years_service);
}
void CalcRaise()
{
bonusA = salary * .02;
bonusB = salary * .05;
bonusC = salary * .10;
if (years_service < 2)
{
printf("Here is your bonus: %lf", bonusA);
}
else if (years_service > 5 && years_service < 10)
{
printf("Here is your bonus: %lf", bonusB);
}
else
{
printf("Here is your bonus: %lf", bonusC);
}
}
int main()
{
GetInput();
CalcRaise();
return 0;
}

Passing Argument into function

Write a C program to read a rupee amount (integer value) and break it
up into the smallest possible number of bank notes.
Assume bank notes are in the denominations 2000, 500, 200, 100, 50, 20
and 10.
I am trying to pass amount into the denCAL() function and want to update it everytime the function is called but the value of amount remains same.
Please provide the solution for my problem and a better approach for the solution and also do le me know some good programming practises which are missing here.
#include <stdio.h>
int amount, note, den;
int denCAL(amount, den){
note = amount/den;
amount -= note*den;
printf("Number of %d notes are:%d\n", den, note);
}
int notes(){
printf("Enter the amount in rupees: ");
scanf("%d", &amount);
if(amount >= 2000){
denCAL(amount, 2000);
}
if(amount >= 500){
denCAL(amount, 1000);
}
if(amount >= 200){
denCAL(amount, 500);
}
if(amount >= 100){
denCAL(amount, 100);
}
if(amount >= 50){
denCAL(amount, 50);
}
if(amount >= 20){
denCAL(amount, 20);
}
if(amount >= 10){
denCAL(amount, 10);
}
}
int main(){
notes();
}
OUTPUT
Enter the amount in rupees: 30020
Number of 2000 notes are: 15
Number of 1000 notes are: 30
Number of 500 notes are: 60
Number of 100 notes are: 300
Number of 50 notes are: 600
Number of 20 notes are: 1501
Number of 10 notes are: 3002
int nominals[] = {2000, 500, 200, 100, 50, 20, 10, 0};
void getNominals(unsigned money, int *result)
{
int *nm = nominals;
while(*nm && money)
{
*result++ = money / *nm;
money %= *nm++;
}
}
int main(void)
{
int result[sizeof(nominals) / sizeof(nominals[0])] = {0};
getNominals(30020, result);
for(size_t index = 0; nominals[index]; index++)
{
printf("%d = %d\n", nominals[index], result[index]);
}
}
But in your code you need:
add the return statement:
int denCAL(amount, den)
{
int note = amount/den;
amount -= note*den;
printf("Number of %d notes are:%d\n", den, note);
return amount;
}
and then in every if change denCAL(amount, ...); to
amount = denCAL(amount, ...);
The reason why you're not updating your amount variable, even considering it's a global, it's because in your function denCAL(), by passing amount as a parameter, you're accessing a copy of it. Also you need to specify the type of the input parameters in your function prototype. You should change the code like this:
void denCAL(int den){ // amount is global, no need to pass it
note = amount/den;
amount -= note*den;
printf("Number of %d notes are:%d\n", den, note);
}
void notes(){
printf("Enter the amount in rupees: ");
scanf("%d", &amount);
if(amount >= 2000){
denCAL(2000);
}
/* rest of code */
}
Another approach you could use, instead of using a global variable, is to use pointers for example. You could define amount inside notes(), and remove the global you've already declared.
void denCAL(int* amount, int den){ // passing amount by ADDRESS (so it gets modified)
note = (*amount)/den;
(*amount) -= note*den;
printf("Number of %d notes are:%d\n", den, note);
}
void notes(){
int amount;
printf("Enter the amount in rupees: ");
scanf("%d", &amount);
if(amount >= 2000){
denCAL(&amount, 2000);
}
/* rest of code */
}

Why am I getting the wrong average in C?

I'm new at this and having some trouble. I'm trying to find the average of the grades that are inputed by the user but I realized that if you use a decimal in any of the grades, it's just being calculated as if they are whole numbers.
#include <stdio.h>
int main(void)
{
unsigned int counter;
float grade;
int total;
float average;
int number;
total = 0;
counter = 1;
printf("Number of scores to enter:\t");
scanf("%d", &number);
printf("\n");
while (counter <= number) {
printf("%s%d%s", "Enter the score for Lab ", counter, ":\t");
scanf("%f", &grade);
total = total + grade;
counter = counter + 1;
}
printf("\n");
average = (float) total / number;
printf("Average lab score: %.1f\n", average);
if (grade>=90) {
puts("Letter grade: A");
}
else if (grade>=80) {
puts("Letter grade: B");
}
else if (grade>=70) {
puts("Letter grade: C");
}
else if (grade>=60) {
puts("Letter grade: D");
}
else {
puts("Letter grade: F");
}
return 0;
}
You are capturing scanf("%f", &grade); as a float and then calculating total = total + grade;.
You have defined int total;. You would need to define it as float total;.
You are moving a float variable into an integer which is truncating the decimals you had previously entered.
There's no need to ask up front how many data points will be entered. Indeed, that is an anti-pattern. Just do something like:
#include <stdio.h>
int
main(void)
{
unsigned int count = 0;
float grade;
float total = 0.0;
float average;
while( scanf("%f", &grade) == 1 ) {
total += grade;
count += 1;
}
average = total / (float) count;
printf("Average lab score: %.1f\n", average);
fputs("Letter grade: ", stdout);
putchar( average >= 90.0 ? 'A' : average >= 80.0 ? 'B' :
average >= 70.0 ? 'C' : average >= 60.0 ? 'D' : 'F');
putchar('\n');
return average >= 60.0;
}
$ echo 78.2 96.5 80 | ./a.out
Average lab score: 84.9
Letter grade: B
Key points: total needs to be a float type. You must check the value returned by scanf. Always. Probably you want to handle bad input more cleanly that this does. This just throws away all data after an error and computes the average based on whatever data was entered prior to the error. A cleaner solution would abort with an error message. Exercise left for the reader.
A reasonable argument can be made that this is an abuse of the ternary operator; however you want to refactor it, don't repeat yourself by hardcoding the string "Letter grade: " multiple times.
Rather than abusing the ternary operator as above, you may prefer something like:
#include <stdio.h>
int
main(void)
{
unsigned int count = 0;
float grade;
float total = 0.0;
float average;
while( scanf("%f", &grade) == 1 ) {
total += grade;
count += 1;
}
average = total / (float) count;
int s = 'A' + (99 - (int)average) / 10;
printf("Average lab score: %.1f\n", average);
printf("Letter grade: %c\n", s > 'D' ? 'F' : s);
return average >= 60.0;
}

2 questions on typedef struct and averages on grades. Am I doing it correctly In C?

I need help on two questions, Its not homework but its to study for an exam. I need to have these questions because i was allowed 1 full page of notes for the exam. If you could help me these two simple questions for me that would be great. Here are the questions:
"Write a function called getGrades. The function that repeatedly prompts the user for positive integers until the user enters a negative value to stop. The function should return the average of these grades and the highest grade."
"Write a function called Get_Info that takes a pointer to a student structure, (that has three fields: char array called name, an int id, and a double gpa) as its only argument. The function prompts the user for the required information to fill the structure and stores it in the appropriate fields."
What I have so far, Let me know if they are correct and if i need to add anything.
1.
double getGrades() {
double average;
double i;
For(i=1 ; i<i; i++)
{
printf("Enter Grade1:\n");
scanf("%lf", &i);
}
if (i<0)
{
(double) average == (grade1 + grade2 + grade3) / 3;
return average;
}
}
2.
typedef struct {
int id;
double gpa;
char name[SIZE];
} student;
void Get_Info(student list[], int num) {
int i;
for(i=0; i<num; i++) {
printf("\nName:%s", list[i].name);
printf("\nGPA:%lf", list[i].gpa);
printf("\nID: %d\n", list[i].id);
}
}
On #1: The requirement is that the function accept ints. You are scanning for doubles.
The requirement is "The function should return the average of these grades and the highest grade." You only return one double, when two different outputs are called for.
Your for loop is written as "For" (C is case-sensitive), and is based on the test i<i. When will i ever be less than itself??
Here's my version of it.
double getGrades(int* max)
{
int sum = 0;
int input;
int i = 0;
*max = 0;
printf("Enter Grade #%d:\n", i+1);
scanf("%d", &input);
while (input > 0) {
if (*max < input) {
*max = input;
}
sum = sum + input;
i++;
printf("Enter Grade #%d:\n", i+1);
scanf("%d", &input);
}
return i? ((double)sum / i) : 0;
}
Your #2 is much better than your #1, but still has some errors:
The requirement is that the function takes a pointer to a student struct, NOT an array.
It should then print a series of Prompts, and get a series of answers (just as you did in #1).
This is a sequence of printf/scanf.
And when using scanf, you typically pass the ADDRESS of the variable, using &.
(strings are a exception, however)
Here is my version:
typedef struct {
char name[SIZE];
int id;
double gpa;
} student;
void Get_Info(student* ps) {
printf("Enter Name\n");
scanf("%s", ps->name);
printf("Enter ID:\n");
scanf("%d", &ps->id);
printf("Enter GPA\n");
scanf("%lf", &ps->gpa);
}
Try this. It should seem intuitive enough:
double getGrades() {
double average;
double grade;
double total = 0;
int count = 0;
while (1) {
printf("Enter grade: ");
scanf("%d", &grade);
if (grade < 0) {
if (count == 0) {
average = 0;
break;
}
average = total/count;
break;
}
count++;
total += grade;
}
return average;
}

Resources