0

My problem is sort some numbers taken from a txt file. When I compile the file the program stop working.

    #include <stdio.h>
    #include <stdlib.h>



    struct student_grades{
    int number;
    char name[10];
    char surname[10];
    int grade;
    };

    typedef struct student_grades stgrade;


    void bubble_sort(int list[], int n){ //Line 16
  long c, d, t;

  for (c = 0 ; c < ( n - 1 ); c++)
  {
    for (d = 0 ; d < n - c - 1; d++)
    {
      if (list[d] > list[d+1])
      {
        /* Swapping */

        t         = list[d];
        list[d]   = list[d+1];
        list[d+1] = t;
      }
    }
  }
}


int main()
{
    int i=0;
    FILE *stu;  // file tipinde değişken tutacak
    FILE *stub;
    stu= fopen("student.txt","r");
    stub= fopen("stu_order.txt","a");


    stgrade stg[12];
        if(stu!=NULL){
        while(!feof(stu))
        {
            fscanf(stu,"%d",&stg[i].number);
            fscanf(stu,"%s",stg[i].name);
            fscanf(stu,"%s",stg[i].surname);
            fscanf(stu,"%d",&stg[i].grade);
            //fprintf(stub,"%d  %s  %s  %d\n",stg[i].number,stg[i].name,stg[i].surname,stg[i].grade);

               ++i;
        }
        bubble_sort(stg->number,12);    //Line 59

        fprintf(stub,"%d  %s  %s  %d\n",stg[1].number,stg[1].name,stg[1].surname,stg[1].grade); //control that is bubble  success?  

    }
    else
      printf("File Not Found");

    fclose(stu);
    fclose(stub);
    return 0;  

at first i write the line 59

bubble_sort(stg.number,12);    

like this . But it gets error and not compile. I change it with

bubble_sort(stg->number,12);    

this it compiled but stop working and get warning

Formatted Output :
In function 'main':
59 3 [Warning] passing argument 1 of 'bubble_sort' makes pointer from integer without a cast [enabled by default]
16 6 [Note] expected 'int *' but argument is of type 'int'

the student.txt

80701056 Sabri Demirel 45  
52801022 Burak Erkin 68  
13801045 Umut Korkmaz 88  
74801334 Semih Potuk 58  
15678544 Enes Sezer 76  
42125884 Ahmet Can 84  
12355488 Emre Ozdemir 47  
18744125 Ugur Yildiz 64  
62184111 Mustafa Ozturk 80  
18412548 Ugur Akkafa 72  
94541771 Hakan Aktas 92  
36945245 Fatih Yagci 98  
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • your `bubble_sort` function will sort a `int` array, but you want to sort a `struct student_grades` array. That is not possible. You have to create a bubble sort function which can sort a `struct student_grades` array. Note that the swapping will be a bit more difficult, because you have to swap structs. – wimh Jan 09 '15 at 23:04
  • 1
    While fixing the plethora of other things wrong in this code, perhaps fix this: [`while (!feof(stu))`](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) as well. – WhozCraig Jan 09 '15 at 23:23
  • @WhozCraig I think you got it. OP: `while(!feof(stu)) { fscanf(stu,"%d",&stg[i].number); ... fscanf(stu,"%d",&stg[i].grade);` --> `while (4 == fscanf(stu,"%d%9s%9s%d",&stg[i].number,stg[i].name,stg[i].surname,&stg[i].grade)) {` – chux - Reinstate Monica Jan 09 '15 at 23:26

3 Answers3

0

Well, your compiler's output tells it like it is:

Your bubble_sort function takes a pointer, but you hand it an integer.

Pointers, addresses, arrays and integers are important C concepts, and I'm afraid you must brush up on your basic C knowledge; reading a bit of reference code would help you understand how to solve your problem. I know that you're most probably new to C and this answer is an answer but not immediately solving your problem, but there are just too many things to explain here, and it doesn't really help you either if someone else comes along and flags your question as being of low-quality.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
  • 1
    The format specifiers in conjunction with the values passed to `fscanf` are correct (mostly). `%s` expects `char*`, which both `name` and `surname` members will convert to when expressed as parameters. If anything is wrong with the OP's `fscanf` code is it (a) a failure to check the results for success/failure, and (b) failure to limit the `%s` format specifier to the size of the char buffer being passed. There are plenty of things wrong in the code. Why you singled out something that is right (passing `name` and `surname` as is done by the OP) seems odd. – WhozCraig Jan 09 '15 at 23:20
  • 1
    "why do you think it's ok to sometimes use the address of a variable in fscanf (using the & prefix operator) and sometimes not?" --> The C spec does it that way `int n, i; float x; char name[50]; n = fscanf(stdin, "%d%f%s", &i, &x, name);` Are you suggesting the C spec and OP are wrong? – chux - Reinstate Monica Jan 09 '15 at 23:24
  • No, chux, this shows that you don't understand that `char name[50]` makes `name` a `char*`, a pointer to the first `char` in your array. Again, this is extremely basic C! You're absolutely right though, that was badly worded by me. My apologies! The point I was trying to bring across was that he must be aware of what is a pointer and what is an object itself, if he operates on arrays. – Marcus Müller Jan 09 '15 at 23:26
0

This is a code based on your file and your structure stgrade dand which use the quick sort with a complexity equals to O(log(n)) ( qsort function ) instead of the bubble sort from the library stdlib.h and which generates the desired output

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> //qsort function

struct student_grades{
    int number;
    char name[10];
    char surname[10];
    int grade;
};

typedef struct student_grades stgrade;

// the compare function is used by the qsort function to sort the structures 
// according to the grades values
int compare(const void* a, const void* b) 
{
return (*(stgrade *)a).grade - (*(stgrade *)b).grade;   
}

int main(int argc, char *argv[])
{
    FILE *stub, *stu;
    stu= fopen("student.txt","r");
    stub= fopen("stu_order.txt","a");

    stgrade tab[12]; // array that will contain the structures from student.txt file
    int i=0;
    for (i=0;i<12;i++)
    {
       // put the structures on the array
        fscanf(stu,"%d %s %s %d",&tab[i].number,tab[i].name,tab[i].surname,&tab[i].grade);
    }
      // use the qsort function that will sort the structures
    qsort(tab,12,sizeof(stgrade),compare);

    //loop to write the result on the output file
    for (i=0;i<12;i++)
    {
         // the write will be via the function fprintf 
        fprintf(stub,"%d %s %s %d\n",tab[i].number,tab[i].name,tab[i].surname,tab[i].grade);
    }

   // Check the output file :)

    return 0;
}

The code can be improved by checking the opened file !!

  • Thanks a lot ! I understand that my process isn't suitable for bubble sort and we use quick sort instead of bubble sort. and you use for loop instead of while. My teacher said that the using !feof() prevent the errors. But if we use static array it is not problem. Thanks again :) in Turkish we say "Eyvallah" :) – mehmet salih bindak Jan 09 '15 at 23:45
  • Don't use `while(!feof(file))` in your next program and here is why [link](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) !! You are welcome ! – Meninx - メネンックス Jan 09 '15 at 23:48
  • Interesting teacher said that the using `!feof()` prevent the errors. Teacher is wrong. Checking the result of IO functions like `fscanf()` is a far better solution. – chux - Reinstate Monica Jan 09 '15 at 23:49
  • I think he says that for dynamic arrays because it can scan some files in the buffer. – mehmet salih bindak Jan 09 '15 at 23:52
  • if you don't know how many lines are in the file it will be a good problem to solve ! at first you can make a loop to count how many line do you have and then allocate the required memory for the dynamic array ! then you need to point again at the start of the file and do the same thing as in the answer above ! – Meninx - メネンックス Jan 09 '15 at 23:56
0
there were lots of problems with the code 
however the following should have all those problems corrected
and includes error checking


#include <stdio.h>
#include <stdlib.h> // exit
#include <string.h> // memcpy

#define MAX_GRADES (12)

struct student_grades
{
    int number;
    char name[10];
    char surname[10];
    int grade;
};




void bubble_sort(struct student_grades* pList, int n)
{ //Line 16
    long c, d;
    struct student_grades t;

    for (c = 0 ; c < (n - 1); c++)
    {
        for (d = 0 ; d <(n - c - 1); d++)
        {
            if (pList[d].number > pList[d+1].number)
            {
                /* Swapping */

                memcpy(&t, &pList[d], sizeof(struct student_grades));
                memcpy(&pList[d], &pList[d+1], sizeof(struct student_grades));
                memcpy(&pList[d+1], &t, sizeof(struct student_grades));
            } // end if
        } // end for
    } // end for
} // end function: bubble_sort


int main()
{
    FILE *stu = NULL;  // file tipinde değişken tutacak
    FILE *stub = NULL; // rises compiler warning about unused variable

    if( NULL == (stu= fopen("student.txt","r")) )
    { // then, fopen failed
        perror( "fopen for student.txt failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    if( NULL == (stub= fopen("stu_order.txt","a")) )
    { // then, fopen failed
        perror( "fopen for stu_order.txt failed" );
        fclose(stu); // cleanup
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful


    struct student_grades stg[MAX_GRADES];
    char line[1000]; // should be enough for reading 4 fields

    int i=0;
    while((i<MAX_GRADES) && fgets(line, sizeof(line), stu) )
    {
        if( 4 != sscanf(line," %d %s %s %d",
                        &stg[i].number,
                        stg[i].name,
                        stg[i].surname,
                        &stg[i].grade) )
        { // fscanf failed
            perror( "fscanf failed" );
            fclose(stu); // cleanup
            fclose(stub);
            exit( EXIT_FAILURE );
        }

        // implied else, fscanf successful

        //fprintf(stub,"%d  %s  %s  %d\n",stg[i].number,stg[i].name,stg[i].surname,stg[i].grade);

        ++i;
    } // end while

    bubble_sort(stg,i);    //Line 59

    int j;
    for(j=0;j<i;j++)
    {
        fprintf(stub,"%d  %s  %s  %d\n",
                stg[1].number,
                stg[1].name,
                stg[1].surname,
                stg[1].grade); //control that is bubble  success?
    } // end for

    fclose(stu); // leanup
    fclose(stub);
    return 0;
} // end function: main
user3629249
  • 16,402
  • 1
  • 16
  • 17