0

I've being asked to write a program in C that will take data of students from the user(name,marks obtained,roll numbers). Then to write a function that will sort data according to marks obtained(ascending order). Then to write a search function that will search using roll number, and another search function that will search using name.

The code I wrote is:

#include<stdio.h>
#include<string.h>
struct data{
    char roll_No[5],name[15],marks[5];
};
struct data stInfo[50];
struct data temp[50];
void sortMarks(int n, struct data *stInfo){
    int i,j;
    for(i=0;i<n;i++){
        for(j=0;j<n;j++){
            if(stInfo[i].marks>stInfo[j].marks){
                strcpy(temp[i].marks,stInfo[i].marks);
                strcpy(stInfo[i].marks,stInfo[j].marks);
                strcpy(stInfo[j].marks,temp[i].marks);
                strcpy(temp[i].name,stInfo[i].name);
                strcpy(stInfo[i].name,stInfo[j].name);
                strcpy(stInfo[j].name,temp[i].name);
                strcpy(temp[i].roll_No,stInfo[i].roll_No);
                strcpy(stInfo[i].roll_No,stInfo[j].roll_No);
                strcpy(stInfo[j].roll_No,temp[i].roll_No);}}}
    for(i=0;i<n;i++){
        printf("\nAfter sorting data of student %d:
%s,%s,%s\n",i+1,stInfo[i].name,stInfo[i].roll_No,stInfo[i].marks);}             
return;}
void searchRoll_No(int n,char *roll_NoToFind, struct data *stInfo){
    int i;
    for(i=0;i<n;i++){
        if(!strcmp(roll_NoToFind,stInfo[i].roll_No)){
            printf("The student is: %s having marks: %s\n",stInfo[i].name,stInfo[i].marks);
            break;}}
        if(strcmp(roll_NoToFind,stInfo[i].roll_No)){
            printf("Record not found!\n");}
return;}
void searchName(int n,char *nameToFind, struct data *stInfo){
    int i;
    for(i=0;i<n;i++){
        if(!strcmp(nameToFind,stInfo[i].name)){ 
            printf("The student has roll no: %s and marks: %s\n",stInfo[i].roll_No,stInfo[i].marks);
            break;}}
        if(strcmp(nameToFind,stInfo[i].name)){
            printf("Record not found!\n");}
return;}
int main(){
    int n,i;
    printf("Enter the number of students: \n");
    scanf("%d",&n);
    for(i=0;i<n;i++){
        printf("Enter roll no of student %d: \n",i+1);
        scanf("%s",&stInfo[i].roll_No);
        printf("Enter name of student %d: \n",i+1);
        scanf("%s",&stInfo[i].name);
        fflush(stdin);
        printf("Enter marks of student %d: \n",i+1);
        scanf("%s",&stInfo[i].marks);}
    sortMarks(n,stInfo);        
    char roll_NoToFind[5];  
    printf("\nEnter the roll number you want to search: \n");
    scanf("%s",&roll_NoToFind); 
    fflush(stdin);
    searchRoll_No(n,roll_NoToFind,stInfo);
    char nameToFind[15];        
    printf("\nEnter the name you want to search: \n");
    scanf("%s",&nameToFind);
    fflush(stdin);  
    searchName(n,nameToFind,stInfo);            
    return 0;}


The search functions are working fine but the sort function is giving wrong output. Whe data for two students is entered it is sorting correctly(sort marks in ascending order) but when I ener data for more than two students, the data is not being sort in ascending order. I want that if there are 5 students and there marks are entered randomly,then sorting must be done and whole data must be displayed according to marks. I think there is an issue with loop condition but I can't figure it out.

  • 2
    `stInfo[i].marks>stInfo[j].marks` does not compare strings. You would have noticed something strange if you tried to debug your sort function by stepping through it line by line. – Raymond Chen Jan 14 '23 at 18:03
  • Please use [the standard `qsort` function](https://en.cppreference.com/w/c/algorithm/qsort) instead of making your own sorting. – Some programmer dude Jan 14 '23 at 18:07
  • 1
    If you're required to write your own sorting, you can assign structure object like any other variables. Like e.g. `struct data temp = stInfo[i]; stInfo[i] = stInfo[j]; stInfo[j] = temp;` – Some programmer dude Jan 14 '23 at 18:09
  • For pity's sake, use structure assignment to swap two entries in the array. It was advertised as "coming soon" in K&R 1st Edition, 1978. It's been in C since long before there was a standard. And you don't need an array of temporary values for the swapping: `struct data temp = stInfo[i]; stInfo[i] = stInfo[j]; stInfo[j] = temp;` would do the swap much more succinctly and probably a bit faster too. – Jonathan Leffler Jan 14 '23 at 18:09
  • Also, a line like `strcpy(stInfo[j].roll_No,temp[i].roll_No);}}}` with 3 close braces tucked at the end of a single line (closing one `if` statement and two `for` loops) is non-idiomatic C. The braces should be visible under the statement that starts the block. If you want to code in Python, use Python, not C. – Jonathan Leffler Jan 14 '23 at 18:12
  • Please use a more orthodox indentation style for C. I strongly recommend either Allman (which is what I use, more or less) or some version of 1TBS (which is used by many other people). See Wikipedia on [Indentation Style](https://en.wikipedia.org/wiki/Indentation_style) for information about the variants. The Pico style, especially with multiple `}` markers on a single line, is anathema in C. Multiple close braces on a single line is a no-no; multiple consecutive close braces at the same indent level is another. – Jonathan Leffler Jan 14 '23 at 18:15
  • @Someprogrammerdude I've been assigned to design a sort function – Hadiya Kashif Jan 14 '23 at 18:19
  • @Hadiya ```fflush(stdin)``` is undefined behaviour. – Harith Jan 14 '23 at 18:20
  • @Hadiya the array name is a constant pointer to the first element of the array, so you do not need to use ```&``` in ```scanf``` with the ```%s``` format specifier. – Harith Jan 14 '23 at 18:21
  • @Hadiya Change ```if(stInfo[i].marks>stInfo[j].marks)``` to ```if (strcmp (stInfo[i].marks, stInfo[j].marks ) > 0)```. NB that a positive value is returned when the first string is greater than the second string. – Harith Jan 14 '23 at 18:25
  • @Hadiya spacebar makes for readability. ```for (size_t i = 0; i < MAX; i++)``` is much more clearer and readable than ```for(size_t i=0;i – Harith Jan 14 '23 at 18:35
  • The calls to ```scanf``` can also be replaced by ```fgets```. Or if you insist upon using ```scanf```, at least use a width specifier to limit the input and check its return value. – Harith Jan 14 '23 at 18:37
  • Precede the pointers in the function parameters with ```const``` if they're not modified in the function. – Harith Jan 14 '23 at 18:38
  • Use ```size_t``` instead of ```int``` for loop indexes, and limit its scope. ```for (size_t i = 0; i < MAX; i++)``` instead of ```int i;``` ```for(i=0;i – Harith Jan 14 '23 at 18:40
  • @Haris can you please elaborate what are you saying?Can you correct that part of my code and send it here? Since I'm a beginner and don't know much about assigning structs. – Hadiya Kashif Jan 14 '23 at 18:42
  • Given two ```struct```s ```s1``` and ```s2```, the statement ```s1 = s2``` copies the ```struct``` ```s2``` to ```s1```. – Harith Jan 14 '23 at 18:44
  • So does ```memcpy ( (void *) &s1, (void *) &s2, sizeof s1)```. – Harith Jan 14 '23 at 18:48

0 Answers0