hi guys been using this site for a while now for tips but never posted before (first time for everything i suppose) anyway doing an assignment for college (Manufacturing degree) so probably basic to some of you. basically
the problem is in the search by student name void near the bottom the program runs but crashes as soon as i enter the name any help would be really appreciated
#include <stdlib.h>
#include <stdio.h>
#define SIZE 2
struct Student
{
long StudentID;//works
char fname[21];//works
char sname[21];//does not work
int year;//works
char course[51];//works
float results_semester_1[6];//works
float results_semester_2[6];//works
int free; // 1 means its free, 0 means its not
};
struct Student BENG[SIZE];
int menu(); // function prototype
void add_student(); // function prototype
void display_students(); // function prototype
void display_results(); // function prototype
void search_for_student_studentID(); // function prototype
void search_for_student_by_name(); // function prototype
void delete_student(); // function prototype
void initialise_database(); // function prototype
void Run_statistics_for_individual_student(); // function prototype
void Run_statistics_for_all_student(); // function prototype
int linear_search(long); // function prototype
int linear_search_sname(char); // function prototype
int main()
{
initialise_database(); // call the function to set all free positions to 1
for(;;) // infinite loop
{
switch(menu()) // calling function menu within switch
{
case 1:
add_student(); // calling function add_student
break;
case 2:
delete_student(); // calling function delete_student
break;
case 3:
display_students(); // calling function display_students
break;
case 4:
search_for_student_studentID(); // calling function display_students
break;
case 5:
search_for_student_by_name(); // calling function display_students
break;
case 6:
Run_statistics_for_individual_student(); // calling function display_students
break;
case 7:
Run_statistics_for_all_student(); // calling function display_students
break;
case 8:
display_results(); // calling function display_students
break;
case 9:
printf("Quitting Program\n");
exit(1);
default:
printf("Invalid option chosen\n\n");
}
} // end of infinite loop
return 0;
}
void add_student()
{
int freepos = -1, i, j,k,year;
for(i = 0; i < SIZE; i++)
{
if(BENG[i].free == 1)
{
freepos = i;
break;
}
}
if(freepos != -1)
{
do
{
printf("Enter student ID:\n");
scanf("%ld", &BENG[freepos].StudentID);
}
while(BENG[freepos].StudentID<10000000 ||BENG[freepos].StudentID>99999999);
printf("Enter firstname:\n");
scanf("%s", BENG[freepos].fname);
printf("Enter surname:\n");
scanf("%s", BENG[freepos].sname);
do
{
printf("Enter year of course:\n");
scanf("%d", &BENG[freepos].year);
}
while(BENG[freepos].year < 1 || BENG[freepos].year > 4);
printf("Enter course name:\n");
scanf("%s", BENG[freepos].course);
for(j = 0; j < 6; j++)
{
printf("Enter result of semester 1 Module %d:\n", j+1);
scanf("%f", &BENG[freepos].results_semester_1[j]);
}
for(k = 0; k < 6; k++)
{
printf("Enter result of semester 2 Module %d:\n", k+1);
scanf("%f", &BENG[freepos].results_semester_2[k]);
}
BENG[freepos].free = 0; // mark record as taken
}
else
printf("No position free at present\n");
}
void display_students()
{
// output the values just entered
int i, j;
for(i = 0; i < SIZE; i++)
{
if(BENG[i].free == 0) // only print taken records
{
printf("Student ID: %ld:\n", BENG[i].StudentID);
printf("Firstname: %s\n", BENG[i].fname);
printf("Surname: %s\n", BENG[i].sname);
printf("Year: %d\n", BENG[i].year);
printf("Course: %s\n", BENG[i].course);
for(j = 0; j < 6; j++)
{
printf("Result semester 1 Module %d: %0.2f\n", j+1, BENG[i].results_semester_1[j]);
} // end of for
for(j = 0; j < 6; j++)
{
printf("Result semester 2 Module %d: %0.2f\n", j+1, BENG[i].results_semester_2[j]);
} // end of for
} // end of if
} // end of for
}
void display_results()
{
// output the values just entered
int i, j;
for(i = 0; i < SIZE; i++)
{
if(BENG[i].free == 0) // only print taken records
{
for(j = 0; j < 6; j++)
{
printf("Result semester 1 Module %d: %0.2f\n", j+1, BENG[i].results_semester_1[j]);
} // end of for
for(j = 0; j < 6; j++)
{
printf("Result semester 2 Module %d: %0.2f\n", j+1, BENG[i].results_semester_2[j]);
} // end of for
} // end of if
} // end of for
}
int menu()
{
int choice;
printf("1. To add a student\n");
printf("2. To delete a student\n");
printf("3. To display all students\n");
printf("4. Find a student using studentID\n");
printf("5. Find a student by student Surname\n");
printf("6. Find student would you like to run statistics for\n");
printf("7. Find statistics for all students\n");
printf("8. Display results of all students\n");
printf("9. Exit Program\n");
do
{
scanf("%d", &choice);
}
while(choice < 1 || choice > 9);
return choice;
}
void initialise_database()
{
int i;
for(i = 0; i < SIZE; i++) // set all structure variables free to 1
BENG[i].free = 1;
}
void delete_student()
{
long search;
int position,freepos;
printf("Enter the number of student to delete\n");
scanf("%ld",&search);
position = linear_search(search);
if ( position == -1 )
printf("%d is not present in array.\n", search);
else
printf("%d is present at location %d.\n", search, position+1);
BENG[position].free = 1;
return;
}
void search_for_student_studentID()
{
long search;
int position,j,i;
printf("Enter the number to search\n");
scanf("%ld",&search);
position = linear_search(search);
if ( position == -1 )
printf("%d is not present in array.\n", search);
else
printf("%d is present at location %d.\n", search, position+1);
printf("Student ID: %ld:\n", BENG[position].StudentID);
printf("Firstname: %s\n", BENG[position].fname);
printf("Surname: %s\n", BENG[position].sname);
printf("Year: %d\n", BENG[position].year);
printf("Course: %s\n", BENG[position].course);
for(j = 0; j < 6; j++)
{
printf("Result semester 1 Module %d: %0.2f\n", j+1, BENG[i].results_semester_1[j]);
}
for(j = 0; j < 6; j++)
{
printf("Result semester 2 Module %d: %0.2f\n", j+1, BENG[i].results_semester_2[j]);
}
return;
}
void search_for_student_by_name(sname)
{
int position,j,i;
printf("Enter the surname of student to search\n");
scanf("%s",&sname);
position = linear_search_sname(sname);
if ( position == 1 )
printf("%s is not present in array.\n", sname);
else
printf("%s is present at location %d.\n", sname, position+1);
printf("Student ID: %ld:\n", BENG[position].StudentID);
printf("Firstname: %s\n", BENG[position].fname);
printf("Surname: %s\n", BENG[position].sname);
printf("Year: %d\n", BENG[position].year);
printf("Course: %s\n", BENG[position].course);
for(j = 0; j < 6; j++)
{
printf("Result semester 1 Module %d: %0.2f\n", j+1, BENG[i].results_semester_1[j]);
}
for(j = 0; j < 6; j++)
{
printf("Result semester 2 Module %d: %0.2f\n", j+1, BENG[i].results_semester_2[j]);
}
return;
}
int linear_search(long find)
{
int c;
for ( c = 0 ; c < SIZE ; c++ )
{
if (BENG[c].StudentID == find )
{
return c;
break;
}
}
return -1;
}
int linear_search_sname(char find)
{
int c;
for ( c = 0 ; c < SIZE ; c++ )
{
if (BENG[c].sname[21] == find )
{
return c;
break;
}
}
return -1;
}
void Run_statistics_for_individual_student()
{
long search;
int position,j,i,k,r,max,minsums,min=100;
float sums = 0,maxsums=0;
printf("Enter the number to search\n");
scanf("%ld",&search);
printf("The statistics for student ID:\n",search);
position = linear_search(search);
if ( position == -1 )
printf("%d is not present in array.\n", search);
else
for(i = 0; i < 6; i++)
{
sums += BENG[position].results_semester_1[i];
}
printf("Average grade over 6 subjects for this student in semester 1 is %0.2f marks\n", sums/6);
for(i = 0; i < 6; i++)
{
maxsums = BENG[position].results_semester_1[i];
}
if(maxsums>max)
{
max=maxsums;
} // end of if
printf("Max grade for this student in semester 1 is %d\n", max);
{
for(k = 0; k < 6; k++)
{
if(BENG[position].results_semester_1[k]<min)
{
min=BENG[position].results_semester_1[k];
} // end of if
}// end of for
printf("Min grade for this student in semester 2 is %d\n", min);
}
for(i = 0; i < 6; i++)
{
sums += BENG[position].results_semester_2[i];
}
printf("Average grade over 6 subjects for this student in semester 2 is %0.2f marks\n", sums/6);
for(i = 0; i < 6; i++)
{
maxsums = BENG[position].results_semester_2[i];
}
if(maxsums>max)
{
max=maxsums;
} // end of if
printf("Max grade for this student in semester 2 is %d\n", max);
{
for(k = 0; k < 6; k++)
{
if(BENG[position].results_semester_2[k]<min)
{
min=BENG[position].results_semester_2[k];
} // end of if
}// end of for
printf("Min grade for this student in semester 2 is %d\n", min);
}
return ;
}
void Run_statistics_for_all_student()
{
// output the values just entered
int i,j,k, max,min=100;
float sums,maxsums=0;
{
for(i = 0; i < SIZE; i++)
if(BENG[i].free == 0) // only print taken records
{
for(j = 0; j < 6; j++)
{
for(i = 0; i < SIZE; i++)
{
sums += BENG[i].results_semester_1[i];
} // end of for
} // end of for
} // end of if
printf("Average grade for all students in semester 1 is %0.2f \n", sums/(SIZE*6));
}
{
for(k = 0; k < SIZE; k++)
if(BENG[i].free == 0) // only print taken records
{
for(j = 0; j < 6; j++)
{
for(i = 0; i < SIZE; i++)
{
maxsums = BENG[i].results_semester_1[i];
}
if(maxsums>max)
{
max=maxsums;
}
}// end of for
}// end of if
}
printf("Max grade for all student in semester 1 is%d\n", max);
{
for(k = 0; k < SIZE; k++)
if(BENG[k].free == 0) // only print taken records
{
for(j = 0; j < 6; j++)
{
for(i = 0; i < 6; i++)
{
if(BENG[i].results_semester_1[i]<min)
{
min=BENG[i].results_semester_1[i];
}
}// end of for
}// end of for
}// end of if
}
printf("Min grade for all student in semester 1 is %d\n", min);
return ;
}
There are a large number of errors throughout your code. All of them due to NOT SLOWING DOWN AND THINKING ABOUT EACH LINE (and part of each line). C is an exact language. That is one of its strengths. There is no such thing as close enough in either syntax or logic. One way to find most of these ...oversights... is to compile with warnings turned on. A compile string for your program should at a minimum contain -Wall -Wextra. For example:
gcc -Wall -Wextra -o student_database student_database.c
That will catch most of your basic syntax and variable type mismatch problems. Eliminate each and every warning. The compiler didn't accidentally throw them. They mean something.
That being said, I have eliminated the warnings in your code. I have been through the add_student function to the extent that it will accept input and prevent newlines from remaining in the input buffer prior to the next entry. I have corrected other areas just to the extent to resolve the compiler warnings. Your code still needs lots of work. This will give you a good start and eliminate that overwhelmed feeling (for the time being). Work through your code, look at the corrections I've made. Slow down -- and you will do fine.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define SIZE 4
struct Student
{
long StudentID;//works
char fname[21];//works
char sname[21];//does not work
int year;//works
char course[51];//works
float results_semester_1[6];//works
float results_semester_2[6];//works
int free; // 1 means its free, 0 means its not
};
struct Student BENG[SIZE];
int menu(); // function prototype
void add_student(); // function prototype
void display_students(); // function prototype
void display_results(); // function prototype
void search_for_student_studentID(); // function prototype
void search_for_student_by_name(); // function prototype
void delete_student(); // function prototype
void initialise_database(); // function prototype
void Run_statistics_for_individual_student(); // function prototype
void Run_statistics_for_all_student(); // function prototype
int linear_search(long); // function prototype
int linear_search_sname(char*); // function prototype
int main()
{
initialise_database(); // call the function to set all free positions to 1
for(;;) // infinite loop
{
switch(menu()) // calling function menu within switch
{
case 1:
add_student(); // calling function add_student
break;
case 2:
delete_student(); // calling function delete_student
break;
case 3:
display_students(); // calling function display_students
break;
case 4:
search_for_student_studentID(); // calling function display_students
break;
case 5:
search_for_student_by_name(); // calling function display_students
break;
case 6:
Run_statistics_for_individual_student(); // calling function display_students
break;
case 7:
Run_statistics_for_all_student(); // calling function display_students
break;
case 8:
display_results(); // calling function display_students
break;
case 9:
printf("Quitting Program\n");
exit(1);
default:
printf("Invalid option chosen\n\n");
}
} // end of infinite loop
return 0;
}
void add_student()
{
int freepos = -1;
int i = 0;
int j = 0;
int k = 0;
for(i = 0; i < SIZE; i++)
{
if(BENG[i].free == 1)
{
freepos = i;
break;
}
}
if(freepos != -1)
{
do
{
printf("Enter student ID (8-digits): ");
scanf("%ld%*c", &BENG[freepos].StudentID);
}
while(BENG[freepos].StudentID<10000000 || BENG[freepos].StudentID>99999999);
printf("Enter firstname: ");
scanf("%[^\n]%*c", BENG[freepos].fname);
printf("Enter surname: ");
scanf("%[^\n]%*c", BENG[freepos].sname);
do
{
printf("Enter year of course (1-4): ");
scanf("%d%*c", &BENG[freepos].year);
}
while(BENG[freepos].year < 1 || BENG[freepos].year > 4);
printf("Enter course name: ");
scanf("%[^\n]%*c", BENG[freepos].course);
for(j = 0; j < 6; j++)
{
printf("Enter result of semester 1 Module %d: ", j+1);
scanf("%f%*c", &BENG[freepos].results_semester_1[j]);
}
for(k = 0; k < 6; k++)
{
printf("Enter result of semester 2 Module %d: ", k+1);
scanf("%f%*c", &BENG[freepos].results_semester_2[k]);
}
BENG[freepos].free = 0; // mark record as taken
}
else
printf("No position free at present\n");
}
void display_students()
{
// output the values just entered
int i, j;
for(i = 0; i < SIZE; i++)
{
if(BENG[i].free == 0) // only print taken records
{
printf("Student ID: %ld:\n", BENG[i].StudentID);
printf("Firstname: %s\n", BENG[i].fname);
printf("Surname: %s\n", BENG[i].sname);
printf("Year: %d\n", BENG[i].year);
printf("Course: %s\n", BENG[i].course);
for(j = 0; j < 6; j++)
{
printf("Result semester 1 Module %d: %0.2f\n", j+1, BENG[i].results_semester_1[j]);
} // end of for
for(j = 0; j < 6; j++)
{
printf("Result semester 2 Module %d: %0.2f\n", j+1, BENG[i].results_semester_2[j]);
} // end of for
} // end of if
} // end of for
}
void display_results()
{
// output the values just entered
int i, j;
for(i = 0; i < SIZE; i++)
{
if(BENG[i].free == 0) // only print taken records
{
for(j = 0; j < 6; j++)
{
printf("Result semester 1 Module %d: %0.2f\n", j+1, BENG[i].results_semester_1[j]);
} // end of for
for(j = 0; j < 6; j++)
{
printf("Result semester 2 Module %d: %0.2f\n", j+1, BENG[i].results_semester_2[j]);
} // end of for
} // end of if
} // end of for
}
int menu()
{
int choice;
printf("1. To add a student\n");
printf("2. To delete a student\n");
printf("3. To display all students\n");
printf("4. Find a student using studentID\n");
printf("5. Find a student by student Surname\n");
printf("6. Find student would you like to run statistics for\n");
printf("7. Find statistics for all students\n");
printf("8. Display results of all students\n");
printf("9. Exit Program\n");
do
{
scanf("%d", &choice);
}
while(choice < 1 || choice > 9);
return choice;
}
void initialise_database()
{
int i;
for(i = 0; i < SIZE; i++) // set all structure variables free to 1
BENG[i].free = 1;
}
void delete_student()
{
long search = 0;
int position = 0;
printf("Enter the number of student to delete\n");
scanf("%ld%*c",&search);
position = linear_search(search);
if ( position == -1 )
printf("%ld is not present in array.\n", search);
else
printf("%ld is present at location %d.\n", search, position+1);
BENG[position].free = 1;
return;
}
void search_for_student_studentID()
{
long search = 0;
int position = 0;
int j = 0;
printf ("Enter the number to search: ");
scanf ("%ld%*c",&search);
position = linear_search (search);
if ( position == -1 )
printf("%ld is not present in array.\n", search);
else
printf("%ld is present at location %d.\n", search, position+1);
printf("Student ID: %ld:\n", BENG[position].StudentID);
printf("Firstname: %s\n", BENG[position].fname);
printf("Surname: %s\n", BENG[position].sname);
printf("Year: %d\n", BENG[position].year);
printf("Course: %s\n", BENG[position].course);
for(j = 0; j < 6; j++)
{
printf("Result semester 1 Module %d: %0.2f\n", j+1, BENG[position].results_semester_1[j]);
}
for(j = 0; j < 6; j++)
{
printf("Result semester 2 Module %d: %0.2f\n", j+1, BENG[position].results_semester_2[j]);
}
return;
}
void search_for_student_by_name (char *sname)
{
int position = 0;
int j = 0;
printf("Enter the surname of student to search\n");
scanf("%[^\n]%*c", sname);
position = linear_search_sname(sname);
if ( position == 1 )
printf("%s is not present in array.\n", sname);
else
printf("%s is present at location %d.\n", sname, position+1);
printf("Student ID: %ld:\n", BENG[position].StudentID);
printf("Firstname: %s\n", BENG[position].fname);
printf("Surname: %s\n", BENG[position].sname);
printf("Year: %d\n", BENG[position].year);
printf("Course: %s\n", BENG[position].course);
for(j = 0; j < 6; j++)
{
printf("Result semester 1 Module %d: %0.2f\n", j+1, BENG[position].results_semester_1[j]);
}
for(j = 0; j < 6; j++)
{
printf("Result semester 2 Module %d: %0.2f\n", j+1, BENG[position].results_semester_2[j]);
}
return;
}
int linear_search(long find)
{
int c = 0;
for ( c = 0 ; c < SIZE ; c++ )
if (BENG[c].StudentID == find )
return c;
return -1;
}
int linear_search_sname(char *find)
{
int c = 0;
for ( c = 0 ; c < SIZE ; c++ )
if (strcmp (BENG[c].sname, find) == 0 )
return c;
return -1;
}
void Run_statistics_for_individual_student()
{
long search = 0;
int position = 0;
int i = 0;
int k = 0;
int max = 0;
int min = 100;
float sums = 0,maxsums=0;
printf("Enter the number to search\n");
scanf("%ld",&search);
printf("The statistics for student ID (%ld):\n",search);
position = linear_search(search);
if ( position == -1 )
printf("%ld is not present in array.\n", search);
else
for(i = 0; i < 6; i++)
{
sums += BENG[position].results_semester_1[i];
}
printf("Average grade over 6 subjects for this student in semester 1 is %0.2f marks\n", sums/6);
for(i = 0; i < 6; i++)
{
maxsums = BENG[position].results_semester_1[i];
}
if(maxsums>max)
{
max=maxsums;
} // end of if
printf("Max grade for this student in semester 1 is %d\n", max);
{
for(k = 0; k < 6; k++)
{
if(BENG[position].results_semester_1[k]<min)
{
min=BENG[position].results_semester_1[k];
} // end of if
}// end of for
printf("Min grade for this student in semester 2 is %d\n", min);
}
for(i = 0; i < 6; i++)
{
sums += BENG[position].results_semester_2[i];
}
printf("Average grade over 6 subjects for this student in semester 2 is %0.2f marks\n", sums/6);
for(i = 0; i < 6; i++)
{
maxsums = BENG[position].results_semester_2[i];
}
if(maxsums>max)
{
max=maxsums;
} // end of if
printf("Max grade for this student in semester 2 is %d\n", max);
{
for(k = 0; k < 6; k++)
{
if(BENG[position].results_semester_2[k]<min)
{
min=BENG[position].results_semester_2[k];
} // end of if
}// end of for
printf("Min grade for this student in semester 2 is %d\n", min);
}
return ;
}
void Run_statistics_for_all_student()
{
// output the values just entered
int i,j,k, max,min=100;
float sums,maxsums=0;
{
for(i = 0; i < SIZE; i++)
if(BENG[i].free == 0) // only print taken records
{
for(j = 0; j < 6; j++)
{
for(i = 0; i < SIZE; i++)
{
sums += BENG[i].results_semester_1[i];
} // end of for
} // end of for
} // end of if
printf("Average grade for all students in semester 1 is %0.2f \n", sums/(SIZE*6));
}
{
for(k = 0; k < SIZE; k++)
if(BENG[i].free == 0) // only print taken records
{
for(j = 0; j < 6; j++)
{
for(i = 0; i < SIZE; i++)
{
maxsums = BENG[i].results_semester_1[i];
}
if(maxsums>max)
{
max=maxsums;
}
}// end of for
}// end of if
}
printf("Max grade for all student in semester 1 is%d\n", max);
{
for(k = 0; k < SIZE; k++)
if(BENG[k].free == 0) // only print taken records
{
for(j = 0; j < 6; j++)
{
for(i = 0; i < 6; i++)
{
if(BENG[i].results_semester_1[i]<min)
{
min=BENG[i].results_semester_1[i];
}
}// end of for
}// end of for
}// end of if
}
printf("Min grade for all student in semester 1 is %d\n", min);
return ;
}
Use/Output:
./bin/student_database
1. To add a student
2. To delete a student
3. To display all students
4. Find a student using studentID
5. Find a student by student Surname
6. Find student would you like to run statistics for
7. Find statistics for all students
8. Display results of all students
9. Exit Program
1
Enter student ID (8-digits): 12345678
Enter firstname: Johnny
Enter surname: Walker
Enter year of course (1-4): 1
Enter course name: UnderwaterMusic
Enter result of semester 1 Module 1: 88.8
Enter result of semester 1 Module 2: 89.8
Enter result of semester 1 Module 3: 90.8
Enter result of semester 1 Module 4: 91.0
Enter result of semester 1 Module 5: 68.7
Enter result of semester 1 Module 6: 66.7
Enter result of semester 2 Module 1: 92.4
Enter result of semester 2 Module 2: 88.4
Enter result of semester 2 Module 3: 82.3
Enter result of semester 2 Module 4: 95.3
Enter result of semester 2 Module 5: 91.2
Enter result of semester 2 Module 6: 88.5
1. To add a student
2. To delete a student
3. To display all students
4. Find a student using studentID
5. Find a student by student Surname
6. Find student would you like to run statistics for
7. Find statistics for all students
8. Display results of all students
9. Exit Program
3
Student ID: 12345678:
Firstname: Johnny
Surname: Walker
Year: 1
Course: UnderwaterMusic
Result semester 1 Module 1: 88.80
Result semester 1 Module 2: 89.80
Result semester 1 Module 3: 90.80
Result semester 1 Module 4: 91.00
Result semester 1 Module 5: 68.70
Result semester 1 Module 6: 66.70
Result semester 2 Module 1: 92.40
Result semester 2 Module 2: 88.40
Result semester 2 Module 3: 82.30
Result semester 2 Module 4: 95.30
Result semester 2 Module 5: 91.20
Result semester 2 Module 6: 88.50
1. To add a student
2. To delete a student
3. To display all students
4. Find a student using studentID
5. Find a student by student Surname
6. Find student would you like to run statistics for
7. Find statistics for all students
8. Display results of all students
9. Exit Program
9
Quitting Program
Additional Suggestions
One suggestion I have for you is to not statically declare the string sizes in the function and just allocate as needed in add_student function. For example:
struct Student
{
long StudentID;//works
char *fname;//works
char *sname;//does not work
int year;//works
char *course;//works
float results_semester_1[6];//works
float results_semester_2[6];//works
int free; // 1 means its free, 0 means its not
};
Then you could simply allow scanf to dynamically allocate memory as needed with for example:
scanf("%m[^\n]%*c", &BENG[freepos].fname);
Additionally, you will see I had to change all the scanf format strings in add_student to prevent a newline from remaining in the input buffer (the result of pressing [enter]) causing your program to skip over the next input. Controlling the state of the input buffer is critical. There are a number of ways to do this, but taking a careful look at man scanf is a good place to start.
There's an error here
void search_for_student_by_name(sname) // just write the type of sname
Related
I have this C code and I struggle with the functions printCol(); and printRow.
When I run the code and call for these functions to print a specific column or a row, they always return the second row or column.
EDITED: I know that many functions are nonsense, but i just started to learn C, please don't be rude...
#include <stdio.h>
#include <stdlib.h>
void printRow1(int *p1, int rowSize) {
for (int i = 0; i < rowSize; i++) {
printf("%d\t", *p1);
p1 += 1;
}
}
void printCol1(int *p, int colSize) {
for (int i = 0; i < colSize; i++) {
printf("%d\n", *p);
p += 4;
}
}
void reverseRow1(int *p2) {
for (int i = 4; i > 0; i--) {
printf("%d\t", *p2);
p2-=1;
}
}
int arr[3][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
};
void printMat() {
int col = 3;
int row = 4;
for (int i = 0; i < col; i ++) {
printf("\n");
for (int j = 0; j < row; j++) {
printf("%d\t", arr[i][j]);
}
}
}
void printCol() {
printf("Which column would you like to print? \t");
int choiceCol;
scanf("%d\n", &choiceCol);
char buf = fgetc(stdin);
if (choiceCol >= 1 && choiceCol <= 4) {
printCol1(&arr[0][choiceCol-1], 3);
} else {
printf("An Error occured\n");
}
}
void printRow() {
printf("Which row would you like to print? \t");
int choiceRow;
scanf("%d\n", &choiceRow);
char buf = fgetc(stdin);
if (choiceRow >= 1 && choiceRow <= 3){
printRow1(&arr[choiceRow-1][0], 4);
} else {
printf("An Error occured\n");
}
}
void reverseRow() {
printf("which row to reverse?: \t");
int reversedR = scanf("%d\n", &reversedR);
printf("%d\n", reversedR);
reverseRow1(&arr[0][reversedR]);
}
void printMenu() {
printf("\n");
printf("You can choose one of these services: \n");
printf("1. Print matrix tabular form. \n");
printf("2. Print a specific row or a number of rows in sequence \n");
printf("3. Print a specific column or a number of columns in sequence \n");
printf("4. Get the elements of a specific row reversed \n");
printf("5. find the number of prime numbers in a specific row \n");
printf("6. Quit \n");
printf("Please select one to try ");
int answer;
scanf("%d\n", &answer);
int *an = &answer;
switch (*an) {
case 1:
printMat();
printMenu();
break;
case 2:
printCol();
printMenu();
break;
case 3:
printRow();
printMenu();
break;
case 4:
reverseRow();
break;
case 5:
/* code */
break;
case 6:
printf("Bye!\n");
break;
default:
printf("please select carefully! \n");
break;
}
}
int main() {
char buf;
printMat();
printMenu();
return 0;
}
Can anyone please help me understand why this is happening? They are always printing wrong column or row.
Tricky little bug, the problem wasn't with your print functions, but with the way you are reading input. You use things like scanf("%d\n", &answer); which wants to read a %d and a \n. When you enter a number you have to follow it by an enter, which might lead you to believe you need to read the \n, but it doesn't go into the input stream. This is also why in your program you would need to enter the selection twice. The second time it leaves a number in the input stream which is wrongly read to choose the row/column. I have corrected these mistakes in the below code.
#include <stdio.h>
#include <stdlib.h>
void printRow1(int *p1, int rowSize) {
for (int i = 0; i < rowSize; i++) {
printf("%d\t", *p1);
p1 += 1;
}
}
void printCol1(int *p, int colSize) {
for (int i = 0; i < colSize; i++) {
printf("%d\n", *p);
p += 4;
}
}
void reverseRow1(int *p2) {
for (int i = 4; i > 0; i--) {
printf("%d\t", *p2);
p2-=1;
}
}
int arr[3][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
};
void printMat() {
int col = 3;
int row = 4;
for (int i = 0; i < col; i ++) {
printf("\n");
for (int j = 0; j < row; j++) {
printf("%d\t", arr[i][j]);
}
}
}
void printCol() {
printf("Which column would you like to print? \t");
int choiceCol;
scanf("%d", &choiceCol);
if (choiceCol >= 1 && choiceCol <= 4) {
printCol1(&arr[0][choiceCol-1], 3);
} else {
printf("An Error occured\n");
}
}
void printRow() {
printf("Which row would you like to print? \t");
int choiceRow;
scanf("%d", &choiceRow);
if (choiceRow >= 1 && choiceRow <= 3){
printRow1(&arr[choiceRow-1][0], 4);
} else {
printf("An Error occured\n");
}
}
void reverseRow() {
printf("which row to reverse?: \t");
int reversedR = scanf("%d", &reversedR);
printf("%d\n", reversedR);
reverseRow1(&arr[0][reversedR]);
}
void printMenu() {
printf("\n");
printf("You can choose one of these services: \n");
printf("1. Print matrix tabular form. \n");
printf("2. Print a specific row or a number of rows in sequence \n");
printf("3. Print a specific column or a number of columns in sequence \n");
printf("4. Get the elements of a specific row reversed \n");
printf("5. find the number of prime numbers in a specific row \n");
printf("6. Quit \n");
printf("Please select one to try ");
int answer;
scanf("%d", &answer);
switch (answer) {
case 1:
printMat();
printMenu();
break;
case 2:
printCol();
printMenu();
break;
case 3:
printRow();
printMenu();
break;
case 4:
reverseRow();
break;
case 5:
/* code */
break;
case 6:
printf("Bye!\n");
break;
default:
printf("please select carefully! \n");
break;
}
}
int main() {
printMat();
printMenu();
return 0;
}
A few other things I noticed, your menu options for row and column are flipped, and your code assumes the size of the array in several spots (this is very bad practice). If the code should work with different sized arrays then you should be passing the size around, if not then you should use macros to define the size. There may be other issues I didn't notice, but the issue mentioned in the question is now fixed.
int const size = 100;
float grades[size];
char students[size][size];
char temp_students[size][size];
int main() {
int length = 0;
int i = 0;
float g = 0;
printf("How many students do you want to enter? \n ");
scanf("%d", &length);
while((i < length)){
printf("Enter the name and grade \n");
// scanf("%s", students[i]);
char temp;
scanf("%c",&temp); // temp statement to clear buffer
scanf("%[^\n]", students[i]);
strcpy(temp_students[i], students[i]);
printf("Enter the grade again \n");
scanf(" %f", &g);
grades[i] = g;
insertion_sort_float(grades, g, length);
insertion_sort_string(students, students[i], length);
i++;
}
i--;
print_report(grades, students, length);
}
void print_report(float grades[], char students[size][size], int number){
printf("Students Test Report \n");
printf("Students that took the test: %d \n", number);
for (int i = 0; i < number; i++){
for(int j = 0; j < number; j++){
printf("%c", students[i][j]);
}
printf("\n");
}
double average = average_number(grades, number);
double median = median_number(grades, number);
double highest = max_number(grades, number);
double lowest = min_number(grades, number);
printf("Average: %f \n Median: %f \n Highest: %f \n Lowest: %f \n", average, median, highest, lowest);
}
void insertion_sort_string(char students[size][size], char string[], int array_size) {
if (array_size+ 1 < size) {// only do insert when there is free space in array
if (array_size == 0)//empty array, insert at the top directly
strcpy(students[0], string);
int insert_index;//to identify the location
for (int i = 0; i < array_size + 1; i++) {
insert_index = i;
if (strcmp(students[i], string)) // due the sorted property of array,
break;// where the first bigger item showes up, where we should insert
}//end of the first for loop
// if we don't find any bigger item, inset_index will equal to element_num, which means we insert at the tail
for (int j = array_size; j > insert_index; j--) {
strcpy(students[j], students[j-1]);
}// end of the second loop
strcpy(students[insert_index], string); // do the insert
} else {
printf("overflow!");
return;
}
}
This is what happens when the code is run:
Write a program that allows a user to enter the names of students that took a test along with the grades they received.
I am not sure why none of the other names are being stored. Only Gerar is being printed. Also the entire string should be printed: "Gerard 78.5", but that is not happening either.
Some code omitted for post purposes. But important code is included
I need to make a program that stores numbers inside of an array. But it must have no duplicate elements.
int x;
int z[8];
for( x = 0; x<8;x++)
printf("number: ");
scanf("%d",&z[x]);
}
for( x=0;x<8;x++) {
printf("%d ",z[x]);
}
First, initialize the array, so that you do not end up reading an uninitialized value and fail the test.
int user_nums[6] = {0};
Next, you need to have another check in the for loop, to read the number again if it is a duplicate.
The code will look like this.
#include<stdio.h>
int main(){
int x,y;
int exists = 0;
int user_nums[6] = {0};
for( x = 0; x<6;x++){//for loop to get the players selected numbers
do {
exists = 0;
printf("Enter a number(from the #'s 1-42): ");
scanf("%d",&user_nums[x]);
for(y =0; y < x; y++) { //to check for duplicates
if (user_nums[x] == user_nums[y])
{
printf("Number already exists\n ");
exists = 1;
break;
}
}
}while (user_nums[x]<1 || user_nums[x]>42 || exists);//accepts only numbers from 1-42 which are not duplicates (continous to ask you for a number until condition is met).
}
printf("Your numbers: \n");
for( x=0;x<6;x++){
printf("%d ",user_nums[x]); // prints the numbers you inputed.
}
return 0;
}
The following code could work in O(n):
#include<stdio.h>
int main()
{
int user_nums[6];
int index[50];
for (int i = 0; i != sizeof(index) / sizeof(index[0]); ++i)
index[i] = -1;
for (int i = 0; i < sizeof(user_nums) / sizeof(user_nums[0]); ++i) {
for (;;) {
printf("Enter a number(from the #'s 1-42): ");
scanf("%d", user_nums + i);
if (user_nums[i] < 1 || user_nums[i] > 42) {
printf("wrong number\n");
continue;
}
if (index[user_nums[i]] != -1) {
printf("dump number\n");
continue;
}
index[user_nums[i]] = i;
break;
}
}
printf("Your numbers: \n");
for(int i = 0; i < 6; ++i)
printf("%d ", user_nums[i]);
return 0;
}
This is a code where the user has a 'Word Search Game', the user is has a menu where he can choose to do a new puzzle and then show it and try to work it out. The user needs to enter 4 words and those inputted words need to be shown in a matrix for other users to find and play. My problem with my code is when the user has to enter 4 words, the system crashes and exists the program.
Also how can i put those words which are written by the user inside the matrix?
Code below:
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
int main(void)
{
srand((unsigned)time(NULL));
char Matrix[10][10];
char Location[4][4];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
Matrix[i][j] = (rand() % (91 - 65)) + 65;
}
}
int menuChoice;
do
{
system("cls");
puts("WORD SEARCH GAME PUZZLE");
puts("-----------------------");
puts("1. New Puzzle");
puts("2. Show Puzzle");
puts("3. Exit");
puts("-----------------------");
puts("Select your choice: ");
scanf_s("%d", &menuChoice);
switch (menuChoice)
{
case 1: newPuzzle(); break;
case 2: showPuzzle(Matrix); break;
}
} while (menuChoice != 3);
return 0;
}
int newPuzzle()
{
int i;
char word[7];
system("cls");
printf("Enter 4 words of your choice to be entered in the puzzle: \n");
for (i = 0; i < 4; i++)
{
printf("Enter word %d: ", i + 1);
scanf_s("%s", &word);
}
return 0;
}
int showPuzzle(char m[10][10])
{
system("cls");
printf(" ");
char c;
for (c = 'A'; c <= 'J'; ++c)
{
printf("%c ", c);
}
printf("\n\n");
for (int i = 0; i < 10; i++) {
printf("%d ", i);
for (int j = 0; j < 10; j++) {
printf("%c ", m[i][j]);
}
printf("\n");
}
getch();
return 0;
}
I have a database application and after adding and deleteting some records i enter to case 6 to free memory and exit app. I know when I exit the program memory automatic gets free but I do this as teacher says. Same problem with heap corruption I get when delete a record and then i try to free the last record. Below you can find my program. I know it's a bit longer but after much days and hours i can't determine the problem. Below you will find my code.
#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef struct StudentDynamic
{
char* firstName;
char* lastName;
float grade;
}StudentDynamic;
void exportCSV(char *filename, StudentDynamic* pStudents, int nStudents)
{
printf("\n Creating %s.csv file. \n ", filename);
FILE *fp;
filename = strcat(filename, ".csv");
fp = fopen(filename, "wb+");
fprintf(fp, "Student No., First Name, Last Name, Grade");
for (int i = 0; i<nStudents; ++i)
{
fprintf(fp, "\n%d", i + 1);
fprintf(fp, ",%s ", pStudents[i].firstName);
fprintf(fp, ",%s ", pStudents[i].lastName);
fprintf(fp, ",%f ", pStudents[i].grade);
}
fclose(fp);
printf("\n File %s succesfully created!\n", filename);
}
void printStudents(StudentDynamic* pStudents, int nStudents)
{
printf("==========");
printf(" List of Students");
printf(" ========== \n");
for (int i = 0; i < nStudents; ++i)
{
printf("%d. %12s %12s %8.2f", i + 1,
pStudents[i].firstName,
pStudents[i].lastName,
pStudents[i].grade);
printf("\n");
}
}
void rewriteFile(StudentDynamic* pStudents, int nStudents)
{
for (int i = 0; i < nStudents - 1; ++i)
for (int j = i + 1; j < nStudents; ++j)
{
if (pStudents[i].grade > pStudents[j].grade)
{
StudentDynamic aux;
aux = pStudents[i];
pStudents[i] = pStudents[j];
pStudents[j] = aux;
}
}
FILE *rwF;
rwF = fopen("logfile.bin", "wb");
for (int i = 0; i<nStudents; ++i)
{
fprintf(rwF, "%s\n", pStudents[i].firstName);
fprintf(rwF, "%s\n", pStudents[i].lastName);
if (i + 1 == nStudents)
{
fprintf(rwF, "%f", pStudents[i].grade);
break;
}
fprintf(rwF, "%f\n", pStudents[i].grade);
}
fclose(rwF);
}
int main()
{
int nStudents, i = 0;
StudentDynamic* pStudents = NULL;
char auxfirstName[255], auxlastName[255];
float auxGrade, updGrade;
FILE *pFile;
pFile = fopen("logfile.bin", "rb");
if (pFile == NULL)
{
printf("Could not open file or is empty! Exiting...");
exit(2);
}
while (!feof(pFile) && pFile != " ")
{
pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic)*(i + 2));
fscanf(pFile, "%s", auxfirstName);
pStudents[i].firstName = (char*)malloc(strlen(auxfirstName) + 1);
strcpy(pStudents[i].firstName, auxfirstName);
fscanf(pFile, "%s", auxlastName);
pStudents[i].lastName = (char*)malloc(strlen(auxlastName) + 1);
strcpy(pStudents[i].lastName, auxlastName);
fscanf(pFile, "%f", &auxGrade);
pStudents[i].grade = auxGrade;
strcpy(auxfirstName, "");
strcpy(auxlastName, "");
auxGrade = 0;
i++;
}
nStudents = i;
for (int i = 0; i < nStudents - 1; ++i)
for (int j = i + 1; j < nStudents; ++j)
{
if (pStudents[i].grade > pStudents[j].grade)
{
StudentDynamic aux;
aux = pStudents[i];
pStudents[i] = pStudents[j];
pStudents[j] = aux;
}
}
fclose(pFile);
char choice;
printf("\t\t================== STUDENT DATABASE APPLICATION ==================");
printf("\n\n");
printf(" \n\t\t\t============================================");
printf("\n \t\t\t 1. Create Student");
printf("\n \t\t\t 2. Update Record");
printf("\n \t\t\t 3. Delete Record");
printf("\n \t\t\t 4. Export DB to CSV");
printf("\n \t\t\t 5. List Students");
printf("\n \t\t\t 6. Exit Program");
printf(" \n\t\t\t============================================");
printf("\n\n");
printf(" Select Your Choice : ");
getch();
while (1)
{
choice = getchar();
switch (choice)
{
case '1':
nStudents++;
pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (nStudents + 1));
printf("Details of the new student:\n");
printf("First name: ");
scanf("%s", auxfirstName);
pStudents[nStudents - 1].firstName = (char*)malloc(strlen(auxfirstName) + 1);
strcpy(pStudents[nStudents - 1].firstName, auxfirstName);
printf("Last Name: ");
scanf("%s", auxlastName);
pStudents[nStudents - 1].lastName = (char*)malloc(strlen(auxlastName) + 1);
strcpy(pStudents[nStudents - 1].lastName, auxlastName);
printf("Grade: ");
scanf("%f", &auxGrade);
pStudents[nStudents - 1].grade = auxGrade;
i++;
rewriteFile(pStudents, nStudents);
printf("\n Enter Another Choice : ");
break;
case '2':
int idtoUpdate;
printf("Update Records for student number: ");
scanf("%d", &idtoUpdate);
idtoUpdate = idtoUpdate - 1;
if (idtoUpdate>nStudents)
printf("Your number is bigger than number of Students. Enter a correct number.");
else
{
int auxI = idtoUpdate;
printf("\n");
printf("Change details for student number %d. \n", auxI + 1);
printf("type 1 for Yes / type 0 for Next step\n");
int changeChoice = 0, changeCount;
printf("Want to change First name?:");
scanf("%d", &changeChoice);
changeCount = 0;
if (changeChoice == 1)
{
changeCount++;
printf("Change First name: ");
scanf("%s", auxfirstName);
pStudents[auxI].firstName = (char*)malloc(strlen(auxfirstName) + 1);
strcpy(pStudents[auxI].firstName, auxfirstName);
}
changeChoice = 0;
printf("Want to change Last name?:");
scanf("%d", &changeChoice);
if (changeChoice == 1)
{
changeCount++;
printf("Change Last Name: ");
scanf("%s", auxlastName);
pStudents[auxI].lastName = (char*)malloc(strlen(auxlastName) + 1);
strcpy(pStudents[auxI].lastName, auxlastName);
}
changeChoice = 0;
printf("Want to change the Grade?:");
scanf("%d", &changeChoice);
if (changeChoice == 1)
{
updGrade = 0;
changeCount++;
printf("Change Grade: ");
scanf(" %f", &updGrade);
pStudents[auxI].grade = updGrade;
}
if (changeCount != 0)
rewriteFile(pStudents, nStudents);
}
printf("\n Enter Another Choice : ");
break;
case '3':
int idtoDelete;
printf("Delete Records for student number: ");
scanf("%d", &idtoDelete);
idtoDelete = idtoDelete - 1;
if (idtoDelete>nStudents)
printf("Your number is bigger than number of Students. Enter a correct number.");
else
{
for (int i = idtoDelete; i < nStudents - 1; ++i)
{
strcpy(pStudents[i].firstName, pStudents[i + 1].firstName);
strcpy(pStudents[i].lastName, pStudents[i + 1].lastName);
pStudents[i].grade = pStudents[i + 1].grade;
}
free(pStudents[nStudents-1].firstName);
free(pStudents[nStudents - 1].lastName);
nStudents--;
rewriteFile(pStudents, nStudents);
}
printf("\n Enter Another Choice : ");
break;
case '4':
char str[10];
printf("\n Enter the filename (max. 10 characters): ");
scanf("%s", str);
exportCSV(str, pStudents, nStudents);
printf("\n Enter Another Choice : ");
break;
case '5':
printf("\n");
for (int i = 0; i < nStudents - 1; ++i)
for (int j = i + 1; j < nStudents; ++j)
{
if (pStudents[i].grade > pStudents[j].grade)
{
StudentDynamic aux;
aux = pStudents[i];
pStudents[i] = pStudents[j];
pStudents[j] = aux;
}
}
printStudents(pStudents, nStudents);
printf("\n Enter Another Choice : ");
break;
case '6':
for (int i = 0; i < nStudents-1; ++i)
{
free(pStudents[i].firstName);
free(pStudents[i].lastName);
}
free(pStudents);
printf("\n");
printf("\t\t Thank you for using my application.");
printf("\n\n");
exit(0);
}
}
return 0;
}
In one place when you allocate space for an extra record, you use:
pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic)*(i + 2));
I think you are creating one too many records there, should be i + 1
Later on in the code you use
pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (nStudents + 1));
and that appears correct. Since it is the last student record where you have the problem, then this is the issue, when reading in the file you have an extra record at the end. You have an extra record at the end of the array within nothing in it.
When you are deleting a record, you may be copying a long student name into a short buffer.
firstname was allocated so that it was just long enough to fit the students name.
When you delete a record, the next student's name, which could be longer, is copied into the short buffer, running over the end, and destroying the heap
strcpy(pStudents[i].firstName, pStudents[i + 1].firstName); //copy many characters
strcpy(pStudents[i].lastName, pStudents[i + 1].lastName); //into short buffers
Rather than using string copy, you could just free the old names, and reassign the pointers.
free(pStudents[i].firstName);
pStudents[i].firstName = pStudents[i + 1].firstName;
Also, when you change student names, it looks like you allocate more memory, but don't free the old memory