'Sort a binary file with qsort

EDIT 3

THE FILE CONTAINS BYTES - I guess I have to sort the bytes, the task doesn't say more - it says that I pass an argument - the name of a binary file that contains bytes - that's it. And I am trying to work with low-level funcs.

I am trying to sort a binary file using qsort but I got stuck - I dont know how to write the content of a file to a buffer so I could pass it to qsort

What I have done:

int main(int argc, char*argv[]){
        int fd1;
        if((fd1=open(argv[1], O_RDONLY))==-1){
                printf("Error occurred while opening the file");
                exit(-1);
        }

        int size;
        char c;
        while(read(fd1, &c, 1)){
                size=size+1;
        }

        size=size+1;
        close(fd1);

        fd1=open(argv[1], O_RDONLY);
        if(fd1==-1){
                printf("Error occured while opening the file");
        }

        char*buffer;
        buffer=malloc(size);
        setbuf(fd1, buffer);

        //EDIT I TRIED THIS AND IT STILL DOES NOT WORK
        int i=0;
        while(read(fd1, &c, 1)){
            buffer[i]=c;
            i++;
        }

        for(int i=0; i<size;i++){
            printf("lele %s", buffer[i]);
        }


        //EDIT 2: after making buffer[i]=c I get this error Segmentation fault

}

SetBuf does not work this way.. How to make it work? Also, I am trying to use func like open, close, read, write, etc.

c


Solution 1:[1]

Your algorithm for reading a file into a buffer is good:

  1. Open the file
  2. Count bytes in file
  3. Close the file
  4. Allocate the buffer
  5. Open the file
  6. Read the file
  7. Close the file

A bit inefficient, because you read the file twice, but that's fine. You just have to implement it properly; any small mistake will make it look like it doesn't work. Use a debugger to check each step.

Here is my try. I didn't debug, to not deny you the "fun" of debugging. I put comments instead.

int main(int argc, char*argv[])
{
    // 1. Open the file
    int fd1;
    if((fd1=open(argv[1], O_RDONLY))==-1){
        printf("Error occurred while opening the file");
        exit(-1);
    }

    // 2. Count bytes in file
    int size = 0;
    char c;
    while(read(fd1, &c, 1))
        size=size+1;
    // To check that this part is good, print the size here!

    // 3. Close the file
    close(fd1);

    // Allocate the buffer
    char *buffer;
    buffer = malloc(size);
    // Might want to print the buffer here, to make sure it's not NULL

    // 5. Open the file
    fd1=open(argv[1], O_RDONLY);
    if(fd1==-1){
        printf("Error occurred while opening the file");
    }

    // 6. Read the file
    for (int index = 0; index < size; ++index)
        read(fd1, &buffer[index], 1);
    // Might want to print what "read" returns in each iteration, to make sure it's successful

    // 7. Close the file
    close(fd1);
}

As noted by Eric Postpischil, the algorithm is actually not good.

The size of the file at one time does not guarantee the size at another time.

If you want to do that correctly, you must read the file only once. This will make the allocation harder: you cannot calculate the required buffer size, so you have to "guess" an initial size and use realloc.

However, in this small example, this is clearly not the requirement - you can probably ignore the possibility of the file changing asynchronously.


There is another possible problem - I/O error on the file when you read it the second time. This is easy to check, so maybe you should add it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1