C Program to calculate sgpa using structures - c

(QW) Write a well documented modular C program to compute SGPA of 2 students of particular semester containing 3 courses, suitably using structures.
Getting garbage value as output scanning of elements goes perfectly but when it comes to printing it displays random number as output, Is the sgpa calculator part of the code correct?
//reaplced courses with 3 and no of students with 2
#include<stdio.h>
struct studentlist
{
int Rno;
char name[20];
int course_marks[8];
}S[2];
int main()
{
int sgpa[2];
printf("ENTER DETAILS\n");
for(int i=0;i<2;i++)
{
printf("enter details of student %d\n",i);
scanf("%d %s",&S[i].Rno,S[i].name);
for(int j=0;j<3;j++)
{
printf("enter marks coursenumber %d \n",j);
scanf("%d",S[i].course_marks[j]);
}
}
//printing details
for(int i=0;i<2;i++)
{
printf("details of student %d are \n",i);
printf("%d %s",S[i].Rno,S[i].name);
for(int j=0;j<3;j++)
{
printf("coursewise marks for studenet %d are\n",j);
printf("%d\n",S[i].course_marks[j]);
}
}
printf(" \n\n ");
//sgpa calculation
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
sgpa[j]=0;
sgpa[j]+=S[i].course_marks;
}
}
//printing
for(int i=0;i<2;i++)
{
printf("%d",sgpa[i]);
}
}

Your usage of S[j].course_marks is wrong.
It is an array and it will be converted to a pointer in expressions here.
It seems the lines
scanf("%d",S[j].course_marks);
printf("%d\n",S[i].course_marks);
sgpa[j]+=S[i].course_marks;
should be
scanf("%d",&S[i].course_marks[j]);
printf("%d\n",S[i].course_marks[j]);
sgpa[j]+=S[i].course_marks[j];
Also the loop
for(int j=0;j<3;j++)
{
sgpa[j]=0;
sgpa[j]+=S[i].course_marks;
}
is bad because it accesses spga[2] while spga has only 2 elements spga[0] and spga[1].
Also it looks weird even if it weren't out-of-range access and
sgpa[j]=0;
sgpa[j]+=S[i].course_marks;
is equivalent to
sgpa[j]=S[i].course_marks;
You should rethink the algorithm here.

Related

Program stops working after entering the value for more than 6 users

I have a school project which asks me to write a code using struct and functions, regarding sales in Greek cities. You are prompted to enter the values of 'em. The program works just fine if I enter that there's 6 salesmen, but a number larger than that makes it stop after entering all the values.. An example would be:
Number of salesmen: 7
(
Enter the his id:
Enter his surname:
Enter the number of sales:
Enter the area code:
) x7 times.
Then, when you enter the last value, it would just stop. Not exit, not stop responding/crash, literally just stop, and you would be unable to type anything more, only option would be to exit.
Thing is, there's no error or warning in both the build messages and the log, which has me quite confused.
My guess is that the error is in the function "calcSales" but I wanted to post the whole code just in case you need more info on it.
Could you take a look at the code and tell me if you find anything wrong? Thank you.
#include <stdio.h>
#include "genlib.h"
#include <simpio.h>
#include <string.h>
#define N 20
#define M 4
struct{
int id;
char surname[16];
long sales;
int area;
} salesmen[N];
void info(int *count);
void calcSales(int *count);
int main(){
int count;
printf("Give me the number of salesmen:\n");
count=GetInteger();
info(&count);
calcSales(&count);
}
void info(int *count){
for (int i=0; i<*count; i++){
printf("\nInfo for salesman number %d:\n", i+1);
printf("\nGive me his id: ");
salesmen[i].id=GetInteger();
printf("\nGive me his surname: ");
gets(salesmen[i].surname);
printf("\nGive me the number of sales: ");
salesmen[i].sales=GetLong();
printf("\n 1=Thessaloniki, 2= Athens, 3= Volos, 4= Hrakleio \n");
printf("\nLastly, give me the number of his area: ");
salesmen[i].area=GetInteger();
if (salesmen[i].area>4){
printf("\nThe number you are trying to enter doesn't match to an area.\n");
break;
}
}
}
void calcSales(int *count){
long tSales[4];
for (int i=0; i<*count; i++){
tSales[i]=0;
}
for (int i=0; i<*count; i++){
if(salesmen[i].area==1){
tSales[0]+=salesmen[i].sales;
}
if(salesmen[i].area==2){
tSales[1]+=salesmen[i].sales;
}
if(salesmen[i].area==3){
tSales[2]+=salesmen[i].sales;
}
if(salesmen[i].area==4){
tSales[3]+=salesmen[i].sales;
}
}
for (int i=0; i<4; i++){
printf("\nSales for area number %d: %ld\n",i+1, tSales[i]);
}
}
Your guess is correct. The mistake in calcSales function.
Exactly, the following part:
long tSales[4];
for (int i=0; i<*count; i++) {
tSales[i]=0;
}
The *count has value of 20. Which means the loop goes from i = 0 until i = 19.
When you access tSales[i] for i = 4 and above. You're invoking an undefined behavior. It's a memory that you didn't reserve for tSales. I suggest using the following:
long tSales[4];
for (int i=0; i<4; i++) {
tSales[i]=0;
}
Or better:
long tSales[4];
for (int i=0; i<sizeof(tSales)/sizeof(tSales[0]); i++) { // number of elements is the total size of array divided by the size of one element.
tSales[i]=0;
}
Or even better, you don't need a loop at all:
long tSales[4] = {0};
Besides your problem:
For the code you're providing, you don't need to pass a pointer to the functions.
You can make the code look as follows:
#include <stdio.h>
#include "genlib.h"
#include <simpio.h>
#include <string.h>
#define N 20
#define M 4
struct{
int id;
char surname[16];
long sales;
int area;
} salesmen[N];
void info(int count);
void calcSales(int count);
int main(){
printf("Give me the number of salesmen:\n");
int count=GetInteger(); // I've made declaration and assignment in same line. That seems cleaner to me.
info(count);
calcSales(count);
}
void info(int count){
for (int i=0; i<count; i++){
printf("\nInfo for salesman number %d:\n", i+1);
printf("\nGive me his id: ");
salesmen[i].id=GetInteger();
printf("\nGive me his surname: ");
gets(salesmen[i].surname);
printf("\nGive me the number of sales: ");
salesmen[i].sales=GetLong();
printf("\n 1=Thessaloniki, 2= Athens, 3= Volos, 4= Hrakleio \n");
printf("\nLastly, give me the number of his area: ");
salesmen[i].area=GetInteger();
if (salesmen[i].area>4 || salesmen[i].area < 1){ // Added an extra condition.
printf("\nThe number you are trying to enter doesn't match to an area.\n");
break;
}
}
}
void calcSales(int count){
long tSales[4] = {0};
for (int i=0; i<count; i++){
tSales[salesmen[i].area - 1]+=salesmen[i].sales; // No need for if conditions.
}
for (int i=0; i<4; i++){
printf("\nSales for area number %d: %ld\n",i+1, tSales[i]);
}
}

Segmentation fault in my program

My sorting program results in a "segmentation fault 11":
#include <stdio.h>
int main()
{
// Asking user for number of inputs in an array
int n;
do {
printf ("enter the number of intigers you want to sort\n");
scanf("%d",&n);
}while (n<=1);
int sort [n];
printf ("please enter %d numbers\n",n);
for (int i=0; i<n; i++) {
scanf("%d",&sort[i]);
}
printf("you entered\n ");
for (int i=0; i<n; i++) {
printf(" %d ",sort[i]);
}
printf("\n");
int k,c,i,x;
for (i=0;i<n;i++) {
if (sort[i]<sort[i-1]){
k=i-2;
while (sort[k]>sort[i]){
k--;
}
k++;
x =sort[i];
c=i;
for (c=i;c>k;c++){
sort[c-1]=sort[c];
}
sort[k]=x;
}
}
printf ("Sorted numbers :-\n");
for (int i=0; i<n; i++) {
printf ("%d ",sort[i]);
}
printf ("\n");
return 0;
}
Now I have looked up the internet and found that it is caused because a variable has value that exceeds the system's memory limit. But cannot understand that concept.
for (i=0;i<n;i++)
{
if (sort[i]<sort[i-1])
You are accessing array out of its bounds.Maybe you want to start your loop from 1.Also
k=i-2;
while (sort[k]>sort[i])
will access index beyond 0 for example if i is 0 or 1 or 2
k = i - 2; looks unstable for low values of i.
sort[i - 1] is undefined when i is zero.
The thing causes the behaviour of sort[k] to be undefined.
Moral of the story: check all the array indexes before attempting to retrieve an array element. Your debugger will help you here.
In addition to all said before:
c=i;
for (c=i;c>k;c++){
sort[c-1]=sort[c];
}
sort[k]=x;
i can be 0 -> c can be 0 -> sort[c-1] would also result in accessing array out of bounds.
There is no need to initialize c=i twice. It is enough to do it in the loop-declaration

C: Array of Structs (Input into int array within array of structs)

Hi I have to create a database that stores students number, name and also stores an array of course marks (1-N) in C Programming Language.
Everything worked until I started coding for the array of course marks. Then every time I compiled the code it kept crashing as soon as it asked to input the course marks.
Can you please tell me where I'm going wrong in my programming for this task? I have attached it to this message.
The program worked for inputting the name, student number, however I could not get the program to input array of marks. I have asked how many course marks to be entered and then used a for loop within the "void insert(void)" function to keep inputting the course marks into the array *marks. I am referring specifically to lines 24 to 30 in my programming code.
Always at this point the program kept crashing and I could not proceed further to enter more names or print the stored student details.
I think there is a problem with this part:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n");
scanf("%d", &(list[num_students].marks[num_marks]));
}
Anyway here is the full code:
#include <stdio.h>
#include <string.h>
struct student{
int number;
char name[10];
int marks[5];
};
struct student list[10];
int num_students = 0;
int num_marks = 0;
int *p;
void insert(void)
{
int student_number;
int i;
printf("Enter number: \n");
scanf("%d", &list[num_students].number);
printf("Enter NAME: \n");
scanf("%s", &list[num_students].name);
printf("Enter NO of courses: \n");
scanf("%d", num_marks);
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
num_students++; // HOW DO WE INPUT ARRAY MARKS??? MARK1: , MARK2: , MARK3 ,
}
void printtest(void)
{
int i;
for (i=0; i < num_students; i++)
{
printf("Name: \n");
puts(list[i].name);
printf("Number: %d \n", list[i].number);
printf("Mark: %d /100 \n", list[i].marks);
printf("\n");
}
}
int main(void)
{
int code;
int opt1;
int courses, i, k, j, counter;
for (;;){
printf("Enter operation code: \n");
printf("(1) ADD NEW STUDENT DETAILS: \n");
printf("(2) DISPLAY REPORT OF ALL STUDENTS: \n");
scanf(" %d", &code);
switch (code){
case 1 :
insert();
break;
case 2 :
printtest();
break;
default:
printf("Illegal code\n");
printf("\n");
}
}
}
Apart from what others pointed out, I'd like to draw your attention towards the following:
void insert(void)
{
int student_number;
int i;
printf("Enter number: \n");
scanf("%d", &list[num_students].number);
printf("Enter NAME: \n");
scanf("%s", &list[num_students].name);
printf("Enter NO of courses: \n");
scanf("%d", num_marks);
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
num_students++;
}
void printtest(void)
{
int i;
for (i=0; i < num_students; i++)
{
printf("Name: \n");
puts(list[i].name);
printf("Number: %d \n", list[i].number);
printf("Mark: %d /100 \n", list[i].marks);
printf("\n");
}
}
There are three problematic statements:
scanf("%s", &list[num_students].name); This is why beginners should use compilers with all warnings enabled.
printf("Mark: %d /100 \n", list[i].marks); What did you declare marks as in the first place?
scanf("%d", num_marks); Seems like you put & operator where not needed and ignore where needed. Read your textbook before asking a question next time.
Seems like you're having a tough time understanding the concept of arrays and pointers. Read your text book thoroughly before venturing into the world of pointers. If you don't use them correctly, even compiler can't help you.
Also, even if I don't expect your program to have a robust input mechanism, at least array bounds checking is expected. Learn good habits from the beginning. They'll save a lot of your time while debugging later.
Seems to be an error in:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
The crash is probably because num_marks as index indexes beyond the array. Change to:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[i]));
}

Persistent segmentation fault in student grading array program

Creating a program that first takes in maximum amount of points for four assignments. Then it must take in seven students' scores for those four assignments. The program must then output each of the seven students score over the total available points. I can't figure out this pesky segmentation error. Program compiles and input of the maximum points available for the four assignments works just fine, the segmentation comes when I try to enter the students scores. Any help would be greatly appreciated!
#include<stdio.h>
int main (void)
{
int array[4][8];
int max, rows, cols, count;
printf("Please enter the maximum points available for the four assignment");
printf(" (add a space behind each and return when finished): \n");
scanf("%d %d %d %d", &array[0][0], &array[1][0], &array[2][0], &array[3][0]);
max=array[0][0]+array[1][0]+array[2][0]+array[3][0];
printf("Please enter each students set of scores");
printf(" (return after each individual score): \n");
for(cols=1; cols<8; cols++)
{
for(rows=0; rows<4; rows++)
{
scanf("%d", array[rows][cols]);
}
}
for(count=1; count<8; count++)
{
for(cols=1; cols<8; cols++)
{
printf("The points for student #%d, count");
printf(" (%d / %d)",array[0][cols]+array[1][cols]+array[2][cols]+array[3][cols], max);
printf("\n");
}
}
return 0;
}
One of your quotes is misplaced. Change
printf("The points for student #%d, count");
to
printf("The points for student #%d", count);

C program with two dimensional arrays?

in a two dimensional array there are kept the working hours for N workers and M projects,the names of the workers are kept in an array with the name Worker and the name of the projects in an array with the name "Project".Write a program which reads the data and displays the worker with more working hours.So I tried this,but everytime I ran it,it seems to be a logical error,because it says :Give the number of the project,and If I type "2" this is also the number of the workers according to my program,and then it asks for the hours for each worker..
#include<stdio.h>
#include<conio.h>
int main()
{
int i, j, n, worker[100][10], hours[30][100];
printf("The number of the project: ");
scanf("%d", &n);
for (i=0; i<n; i++)
{
printf("Give the worker %d: ", i+1);
scanf("%s", &worker[i]);
}
for (i=0; i<n; i++)
{
printf("\n The worker %s\n", worker[i]);
for (j=0; j<30; j++)
{
printf("The number of the hours for the day %d: ", j+1);
scanf("%d", &hours[i][j]);
}
}
for (i=0; i<n; i++)
{
for (j=0; j<30; j++)
if (hours[i][j]==0)
break;
if (j==30)
printf("%s\n", worker[i]);
}
getch();
return 0;
}
You seem to be taking the input incorrectly.
scanf("%s", &worker[i]);
worker is a 2D array of type int. So, you need to have another index while taking input. Also the format specifier for int is %d. Any decent compiler should have given you warnings during compilation.
Seems to me that you first must ask how many workers (N) and how many projects (M) with something like:
int ii, m, n;
char **worker;
char **project;
printf("How many workers? ");
scanf("%d", &n);
printf("How many projects? ");
scanf("%d", &m);
Then ask for the names of the workers:
// Allocate space for n worker string pointers
worker = (char **)malloc(n * sizeof(char *));
for (ii = 0; ii < n; ++ii)
{
char bufname[1024]; // danger here if input too long
printf("Name of worker[%d]? ", ii + 1);
scanf("%s", bufname);
worker[ii] = strdup(bufname);
}
Then ask for the names of the projects, similarly. Then get the hours, then calculate the max, then free up the dynamically allocated worker & project strings (and the two array of pointers).

Resources