Multipurpose Payroll System C - c

I have a program using unions and structures that calculates pay for an hourly worker or a salary worker. For an hourly worker the hours they work must be less than 80. I implemented that in my code but I get this warning and do not know how to fix it.
Below is my code:
#include <stdio.h>
#include <ctype.h>
#define MAXSIZE 4000
union Employee { //union
struct HourlyPaid { //Struct for Hourly Workers
char name[20];
char Gender[20];
int HoursWorked;
float HourlyRate;
} HourlyPaid;
struct Salary { //struct for Salaried workers
char name[50];
int age;
float salary;
float bonus;
} Salary;
} Employee;
int main(void)
{
int i = 0;
int n = 0;
char option[2];
char s[MAXSIZE];
while(1)
{
puts("\nMULTIPURPOSE PAYROLL SYSTEM");
puts("Please Select an Option to Continue:");
puts("Option A: Calculating Pay for an HOURLY worker");
puts("Option B: Calculating Pay for an SALARIED worker\n");
puts("PRESS ANY OTHER BUTTON TO EXIT\n");
fgets(option, MAXSIZE, stdin);
//putchar(option);
if((option[0]=='a')||(option[0]=='A')) //Condition for Hourly Workers
{
puts("Please enter how many salaries you wish to input:\t");
scanf("%d", &n);
struct HourlyPaid x[n];
for(i = 0; i < n; i++)
{
fputs("Enter Name: ", stdout);
scanf("%s", x[i].name);
fputs("Enter Gender: ", stdout);
scanf("%s", x[i].Gender);
fputs("Enter Hours Worked: ", stdout);
scanf("%d", &x[i].HoursWorked);
fputs("Enter Hourly Rate: ", stdout);
scanf("%f", &x[i].HourlyRate);
}
if (&x[i].HoursWorked > 80 )
{
puts ("Sorry please enter a value less than 80 for hours worked");
}
else
for (i = 0; i < n; i++)
{
printf("\n\tCalculated Salary #%d\n", (i+1));
puts("\t===============================");
printf("\n\tName %d.............%s \n", (i+1),x[i].name);
printf("\tGender %d...........%s \n", (i+1), x[i].Gender);
printf("\tHours Worked %d.....%d \n", (i+1), x[i].HoursWorked);
printf("\tHourly Rate %d......%.2f \n", (i+1), x[i].HourlyRate);
printf("\n\tTotal Salary %d.....%.2f \n", (i+1), (x[i].HourlyRate*x[i].HoursWorked));
puts("\t===============================");
} //End of for
} //End of if
else if((option[0]=='b')||(option[0]=='B')) //Condition for Salaried Workers
{
puts("Please enter how many salaries you wish to input:\t");
scanf("%d", &n);
struct Salary x[n];
//int i;
for(i = 0; i < n; i++)
{
printf("Enter Name %d: ", i+1);
scanf("%s", x[i].name);
printf("Enter Age %d: ", i+1);
scanf("%d", &x[i].age);
printf("Enter Salary %d: ", i+1);
scanf("%f", &x[i].salary);
printf("Enter Bonus %d: ", i+1);
scanf("%f", &x[i].bonus);
}
for (i = 0; i < n; i++)
{
printf("\n\tCalculated Salary #%d\n", (i+1));
puts("\t============================");
printf("\n\tName %d is..........%s \n", (i+1),x[i].name);
printf("\tAge %d is...........%d \n", (i+1), x[i].age);
printf("\tSalary %d is........%.2f \n", (i+1), x[i].salary);
printf("\tBonus %d is.........%.2f \n", (i+1), x[i].bonus);
printf("\n\tTotal Pay %d is.....%.2f \n", (i+1), (x[i].bonus+x[i].salary));
puts("\t============================");
}
} //End of else if
else
{
return 0;
}
fgets(option, MAXSIZE, stdin);
} //End of While
} //End of Main

Try
for(i = 0; i < n; ) // note no i++ here
{
fputs("Enter Name: ", stdout);
scanf("%s", x[i].name);
fputs("Enter Gender: ", stdout);
scanf("%s", x[i].Gender);
fputs("Enter Hours Worked: ", stdout);
scanf("%d", &x[i].HoursWorked);
fputs("Enter Hourly Rate: ", stdout);
scanf("%f", &x[i].HourlyRate);
if (x[i].HoursWorked > 80 )
{
puts ("Sorry please enter a value less than 80 for hours worked");
} else {
i++; //note increment i only if the value is good
}
}
This is not an ideal solution. you may need to enter all details again if HoursWorked > 80

The reason why it does not work is not related to the presence or the absene of the &sign, but because your logic is a bit awkward.
You want this:
for (i = 0; i < n; i++)
{
fputs("Enter Name: ", stdout);
scanf("%s", x[i].name);
fputs("Enter Gender: ", stdout);
scanf("%s", x[i].Gender);
fputs("Enter Hours Worked: ", stdout);
scanf("%d", &x[i].HoursWorked);
do
{
fputs("Enter Hourly Rate: ", stdout);
scanf("%f", &x[i].HourlyRate);
if (x[i].HoursWorked > 80)
{
puts("Sorry please enter a value less than 80 for hours worked\n");
continue;
}
} while (0);
}
If the user enters a number greater then 80, the program simply displays "Sorry, please..." and then asks the user again to enter the number of hours worked.

Related

Why can't I print all the character types of variables in array?

#include <stdio.h>
#include <conio.h>
int main() {
char name[20];
int age[20], i, size;
printf("Enter number of students: ");
scanf("%d", &size);
for (i = 0; i < size; i++)
{
printf("\nEnter Student # %d name: ", i+1 );
scanf("%s", &name[i]);
printf("\nEnter Student # %d age: ", i+1 );
scanf ("\n%d", &age[i]);
}
printf("---");
printf("\n Student Information");
for (i = 0; i < size; i++)
{
printf("\nStudent # %d :\n", i+1);
printf("Name: %c", name[i]); //how do i print the array here?
printf("\nAge: %d", age[i]);
}
return 0;
}
For some reason, I can't display the whole characters that are inputted, and instead, my program produces nothing. What's causing this and how can I fix it?
starboy_b already answered your question, but I want to highlight security issues in your code:
Keep in mind that using scanf to get input like you do is introducing dangerous vulnerabilities to your program.
Why? :
scanf does not know how much allocated space your variables have and does not prevent the user from entering more characters than your buffer can contain. This lead to buffer overflow and can be used to run attacker code.
Your better off e.g. using readline or fgets to get input from user.
#include <stdio.h>
#include <conio.h>
int main() {
char name[20][100];
int age[20], i, size;
printf("Enter number of students: ");
scanf("%d", &size);
for (i = 0; i < size; i++)
{
printf("\nEnter Student # %d name: ", i+1 );
scanf("%s", &name[i]);
printf("\nEnter Student # %d age: ", i+1 );
scanf ("\n%d", &age[i]);
}
printf("---");
printf("\n Student Information");
for (i = 0; i < size; i++)
{
printf("\nStudent # %d :\n", i+1);
printf("Name: %s", name[i]); //how do i print the array here?
printf("\nAge: %d", age[i]);
}
return 0;

'(struct student *)&st' is a pointer; did you mean to use '->'?|

#include<stdio.h>
#include<string.h>
#define MAX 50
struct student
{
int srn;
char stu_name[30];
char course[18];
char addr[50];
};
int main()
{
struct student st[MAX];
int i;
for (i = 0; i < MAX; i++)
{
printf("\nEnter name of the student %d : ", st[i].srn=i+1);
scanf("%s", st[i].stu_name);
printf("\nEnter course of the student %d : ", i+1);
scanf("%s", st[i].course);
printf("\nEnter address of the student %d : ", i+1);
scanf("%s", st[i].addr);
}
for (i = 0; i < MAX; i++)
{
printf("\nname of student %d is %s", i+1, st[i].stu_name);
printf("\ncourse is %s", st[i].course);
printf("\naddr is %s", st[i].addr);
}
return 0;
}
i wrote this code for a school project but codeblocks keeps giving me this error.Anyone know the solution?
main.c|21|error: '(struct student *)&st' is a pointer; did you mean to use '->'?|
You cannot assign values in the same line where you are printing them, thats the whole problem
try this instead might work
st[i+1].srn
instead of
st[i].srn=i+1
The end code should look something like this
int main()
{
struct student st[MAX];
int i;
for (i = 0; i < MAX; i++)
{
st[i].srn = i+1;
printf("\nEnter name of the student %d : ", st[i].srn);
scanf("%s", st[i].stu_name);
printf("\nEnter course of the student %d : ", i+1);
scanf("%s", st[i].course);
printf("\nEnter address of the student %d : ", i+1);
scanf("%s", st[i].addr);
}
for (i = 0; i < MAX; i++)
{
printf("\nname of student %d is %s", i+1, st[i].stu_name);
printf("\nname of student %d is %s", st[i].srn, st[i].stu_name);
printf("\ncourse is %s", st[i].course);
printf("\naddr is %s", st[i].addr);
}
return 0;
}

I can't seem to run an array for a string variable

I've run this code countless times and I'm not sure what's wrong with it. It won't display the 'subj' variable whenever I run the code and choose the '1. Display' option. All I get is the error 'divide error' 'abnormal program termination '→ '
Here's my code:
#include <stdio.h>
#include <conio.h>
char subj[20], name[20], course[20], studentid[20];
float grade[20], hold, gu[20], guadd, gpa, temp, median, mode, max, a[20];
int z, i, h, n, tu, c, unit[20], count;
void disp(int n, int unit[], float grade[], char subj[], char name[], char studentid[], char course[])
{
printf("Name: %s\n", name);
printf("Course: %s\n", course);
printf("Student ID: %s\n", studentid);
printf("\n\nSubject\t\t\tUnits\t\t\tFinal Grade\n");
for(i=0; i<n; i++)
{
printf("%s", subj[i]);
printf("\t\t\t%d\t\t\t", unit[i]);
printf("\%.2f\n", grade[i]);
}
tu=0;
guadd=0;
for(i=0; i<n; i++)
{
gu[i]=grade[i]*unit[i];
tu+=unit[i];
guadd+=gu[i];
}
gpa=guadd/tu;
printf("\n\nSemester Grade Point Average:\t\t\t%.2f\n", gpa);
}
int main()
{
clrscr();
printf("Enter Student Name: ");
scanf ("%s", &name);
printf("Enter Student ID: ");
scanf ("%s", &studentid);
printf("Enter Course: ");
scanf ("%s", &course);
printf("Please Enter the Amount of Subjects Enrolled: ");
scanf ("%d", &n);
for(i=0; i<n; i++)
{
printf("\nPlease Enter the Subject Name: ");
scanf("%s", &subj[i]);
printf("Please Enter the Final Grade for this Subject: ");
scanf ("%f", &grade[i]);
printf("Please Enter Number of Units for this Subject: ");
scanf ("%d", &unit[i]);
}
clrscr();
do
{
printf("\nPlease Choose an Option:\n\n1. Display Grades with GPA\n2. Ascending Order of Grades\n3. Descending Order of Grades\n4. Median and Mode\n5.EXIT\n\nChoice: ");
scanf ("%d", &z);
clrscr();
switch(z)
{
case 1: disp(n, unit, grade, subj, name, studentid, course);
break;
case 2: ascending(n, grade);
break;
case 3: descending(n, grade);
break;
case 4: medmod(n, grade);
break;
}
}
while (z!=5);
getch();
return 0;
}
P.S. I'm new to this so I don't really know what the issue is. Thanks for the help!
Some changes I made to your code and it works.
Replace char subj[20] by char *subj[20] since you need an array of strings, not an array of characters which would be a single string. Then, allocate memory to each of them dynamically (used malloc from C's stdlib.h), say at-least for 100 chars.
Also, the gcc compiler generates warnings good enough to know what's going on, so it becomes quite clear to fix your arguments to printf and scanf functions.
PS : Since conio.h is non-portable, I removed it and its functions from the code.
Modified code :
#include <stdio.h>
#include <stdlib.h>
char *subj[20];
char name[20], course[20], studentid[20];
float grade[20], hold, gu[20], guadd, gpa, temp, median, mode, max, a[20];
int z, i, h, n, tu, c, unit[20], count;
void disp(int n, int unit[], float grade[], char *subj[], char name[],
char studentid[], char course[]) {
printf("Name: %s\n", name);
printf("Course: %s\n", course);
printf("Student ID: %s\n", studentid);
printf("\n\nSubject\t\t\tUnits\t\t\tFinal Grade\n");
for (i = 0; i < n; i++) {
printf("%s", subj[i]);
printf("\t\t\t%d\t\t\t", unit[i]);
printf("\%.2f\n", grade[i]);
}
tu = 0;
guadd = 0;
for (i = 0; i < n; i++) {
gu[i] = grade[i] * unit[i];
tu += unit[i];
guadd += gu[i];
}
gpa = guadd / tu;
printf("\n\nSemester Grade Point Average:\t\t\t%.2f\n", gpa);
}
int main() {
for (i = 0; i < 20; i++)
subj[i] = malloc(sizeof(char) * 100);
printf("Enter Student Name: ");
scanf("%s", name);
printf("Enter Student ID: ");
scanf("%s", studentid);
printf("Enter Course: ");
scanf("%s", course);
printf("Please Enter the Amount of Subjects Enrolled: ");
scanf("%d", &n);
printf("%s %s %s %d", name, studentid, course, n);
for (i = 0; i < n; i++) {
printf("\nPlease Enter the Subject Name: ");
scanf("%s", subj[i]);
printf("%s", subj[i]);
printf("Please Enter the Final Grade for this Subject: ");
scanf("%f", &grade[i]);
printf("Please Enter Number of Units for this Subject: ");
scanf("%d", &unit[i]);
}
do {
printf("\nPlease Choose an Option:\n\n1. Display Grades with GPA\n2. "
"Ascending Order of Grades\n3. Descending Order of Grades\n4. "
"Median and Mode\n5.EXIT\n\nChoice: ");
scanf("%d", &z);
switch (z) {
case 1:
disp(n, unit, grade, subj, name, studentid, course);
break;
case 2:
break;
case 3:
descending(n, grade);
break;
case 4:
medmod(n, grade);
break;
}
} while (z != 5);
return 0;
}

Segmentaiton fault when function is called to input a double into a member of a array, previous input works

For a class assignment in C, I was tasked with writing a program that creates a struct with 4 members, first name, last name, hours, and payrate, after its created, it inputs the user to input the 4 members 3 times, so we have 3 employees. when the program is run, I can input the first and last and hours of the first employee but when it comes to input for the payrate this causes a segmentation fault. Here is my code
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
struct employee
{
char first[30];
char last[30];
double hours;
double payrate;
};
typedef struct employee emp;
int main(void)
{
system("clear");
emp emp[SIZE];
int counter;
for (counter = 0; counter < 3; counter++)
{
input(&emp[counter]);
}
for (counter = 0; counter < 3; counter++)
{
output(emp[counter]);
}
printf("%10s %10s %10s %10s", "First", "Last", "Hours", "Rate");
puts("------------------------");
for (counter = 0; counter < SIZE; counter++)
{
printf("%s %s %d %d \n", emp[30].first, emp[30].last, emp[10].hours, emp[10].payrate);
}
return 0;
}
void output(struct employee emp)
{
printf("First: %s \n", emp.first);
printf("Last: %s \n", emp.last);
printf("Hours: %d \n", emp.hours);
printf("Payrate: %d \n", emp.payrate);
puts("********************************");
}
void input(emp * ptr)
{
printf("Enter first name: ");
scanf("%s", ptr->first);
printf("Enter last name: ");
scanf("%s", ptr->last);
printf("Enter hours worked: ");
scanf("%d", ptr->hours);
printf("Enter payrate: ");
scanf("%d", ptr->payrate);
puts("********************************");
}
Edit#1 I edited some code and it works until the part of the table, it now works but gives out a 0.0000 in the first two colums of the table, here the edited code.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
struct employee
{
char first[30];
char last[30];
double hours;
double payrate;
};
typedef struct employee emp;
int main(void)
{
system("clear");
emp emp[SIZE];
int counter;
for (counter = 0; counter < SIZE; counter++)
{
input(&emp[counter]);
}
for (counter = 0; counter < SIZE; counter++)
{
output(emp[counter]);
}
printf("%10s %10s %10s %10s", "First", "Last", "Hours", "Rate");
puts("\n ------------------------");
for (counter = 0; counter < SIZE; counter++)
{
printf("%s %s %lf %lf \n", emp[30].first, emp[30].last, emp[10].hours, emp[10].payrate);
}
return 0;
}
void output(struct employee emp)
{
printf("First: %s \n", emp.first);
printf("Last: %s \n", emp.last);
printf("Hours: %f \n", emp.hours);
printf("Payrate: %f \n", emp.payrate);
puts("********************************");
}
void input(emp * ptr)
{
printf("Enter first name: ");
scanf("%s", ptr->first);
printf("Enter last name: ");
scanf("%s", ptr->last);
printf("Enter hours worked: ");
scanf("%lf", &ptr->hours);
printf("Enter payrate: ");
scanf("%lf", &ptr->payrate);
puts("********************************");
}
The first problem is that the second argument to scanf should be a pointer. In the case of your strings, they are arrays and basically treated as pointers anyway so they work fine. You need to use the & operator to give it the address of the doubles. The next problem is that the conversion specifier "%d" is for signed integer conversion. For a double, use "%lf" since a double is a long float.
Example:
scanf("%lf", &ptr->hours);

C Program - Don't know why it isn't working

The assignment is to create a program that lets the user enter student names and grades, list the input once all entries have been made, then calculate the average for all grades entered. The program uses structures and loops.
The code I have so far is below. It builds without any errors. However, after I enter the first set of "first name, last name, grade" and hit Enter, the program just sits there with a blinking cursor. I can't seem to figure out what I'm doing wrong.
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 50
// Structure to hold student names and grades
struct student
{
char firstName[MAX_LENGTH];
char lastName[MAX_LENGTH];
int grade;
};
int main ()
{
int i, j, num_students;
int sum = 0;
int cnt = 0;
// Determine how many students will be entered
printf ("Enter the number of students in your class: \n");
scanf ("%d", num_students);
// Obtain student names and grades
printf ("Enter first name, last name and grade separated by spaces. \n");
printf ("Enter END 0 when done entering information.\n\n");
struct student s[num_students];
for (i = 0; i < num_students; ++i) {
scanf ("%s %s %d", s[i].firstName, s[i].lastName, s[i].grade);
if(strcmp(s[i].firstName, "END") == 0) {
break;
}
}
// List students and grades entered
printf ("\nYou entered: \n");
for (j = 0; j < num_students; ++j){
if(strcmp(s[j].firstName, "END") == 0){
break;
}
printf("Name: %s %s, Grade: %d\n", s[i].firstName, s[i].lastName, s[i].grade);
}
// Calculate average of grades entered
for (i = 0; i < num_students; ++i)
{
if (strncmp(s[i].firstName, "END", 3) == 0){
break;
}
else {
sum += s[i].grade;
++cnt;
}
}
printf ("Average of Grades: %f\n", (float)sum/cnt);
return 0;
}
Change
printf("Name: %s %2, Grade: %d\n", s[i].firstName, s[i].lastName, &s[i].grade);
^ Wrong specifier ^ i should be j
to
printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);
Fix the '%2 bug and pass s[i].grade not &s[i].grade
This works for me: I added a line just after inserting the values for quick feedback
#include <stdio.h>
#include <string.h>
#define MAX_ENTRIES 20
#define MAX_LENGTH 50
// Structure to hold student names and grades
struct student
{
char firstName[MAX_LENGTH];
char lastName[MAX_LENGTH];
int grade;
};
int
main ()
{
int i, j;
int sum = 0;
int cnt = 0;
//Obtain student names and grades
printf ("Enter first name, last name and grade separated by spaces. \n");
printf ("Enter END 0 when done entering information.\n\n");
struct student s[MAX_ENTRIES];
for (i = 0; i < MAX_ENTRIES; ++i)
{
scanf ("%s %s %d", s[i].firstName, s[i].lastName, &s[i].grade);
printf ("Name: %s %s, Grade: %d\n", s[i].firstName, s[i].lastName,
s[i].grade);
if (strcmp (s[i].firstName, "END") == 0)
{
break;
}
}
//List students and grades entered
printf ("\nYou entered: \n");
for (j = 0; j < MAX_ENTRIES; ++j)
{
if (strcmp (s[j].firstName, "END") == 0)
{
break;
}
printf ("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName,
s[j].grade);
}
//Calculate average of grades entered
for (i = 0; i < MAX_ENTRIES; ++i)
{
if (strncmp (s[i].firstName, "END", 3) == 0)
{
break;
}
else
{
sum += s[i].grade;
++cnt;
}
}
printf ("Average of Grades: %f\n", (float) sum / cnt);
return 0;
}
Change this line (line no. 42)
printf("Name: %s %2, Grade: %d\n", s[i].firstName, s[i].lastName, &s[i].grade);
to this
printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);
I think it will help you :)
Append the code as ,
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 50
// Structure to hold student names and grades
struct student
{
char firstName[MAX_LENGTH];
char lastName[MAX_LENGTH];
int grade;
};
int main ()
{
int i, j, num_students;
int sum = 0;
int cnt = 0;
// Determine how many students will be entered
printf ("Enter the number of students in your class: \n");
scanf ("%d", &num_students);
// Obtain student names and grades
printf ("Enter first name, last name and grade separated by spaces. \n");
printf ("Enter END 0 when done entering information.\n\n");
struct student s[num_students];
for (i = 0; i < num_students; ++i) {
scanf ("%s %s %d", s[i].firstName, s[i].lastName, &s[i].grade);
if(strcmp(s[i].firstName, "END") == 0) {
break;
}
}
// List students and grades entered
printf ("\nYou entered: \n");
for (j = 0; j < num_students; ++j){
if(strcmp(s[j].firstName, "END") == 0){
break;
}
printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);
}
// Calculate average of grades entered
for (i = 0; i < num_students; ++i)
{
if (strncmp(s[i].firstName, "END", 3) == 0){
break;
}
else {
sum += s[i].grade;
++cnt;
}
}
printf ("Average of Grades: %f\n", (float)sum/cnt);
return 0;
}
Appended line 23 scanf ("%d", &num_students);
line 32 scanf ("%s %s %d", s[i].firstName, s[i].lastName, &s[i].grade);
line 46 printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);
Missed address operator in scanf argument twice:
scanf( "%d", &num_students );
/* .. */
scanf( "%s %s %d", s[i].firstName, s[i].lastName, & s[i].grade );
And index of previous loop was used instead of actual at printing array:
printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);
Handling "END"s is unneccessary when prompting for num_students. Just a suggestion: even loop variable names should be longer than a character. And feel free using double at floating point division unless you miss FPU.

Resources