cfilebubble-sort

Where do I need to write in an output function in my code?


For a task I got a text file with integers in it. There can be a different number of integers in each line, but it can't be more than 30. All integers in the file are separated by spaces. I need to write code which sorts each line depending on its first element and puts the result in the output file. If the first element is a positive value, the elements of the line must be sorted in descending order. If it's a negative value - in ascending order. If the line starts with 0 then it must just stay the same without changing of the order.

I'm using a bubble sort method for this task, but I can't figure out where exactly to write in an output function in my code... This method assumes that there will be a couple iterations going one by one until the order of all elements will be correct. How can I understand when this exact moment comes? Should I add in my code a bool function or something? Or maybe it's way easier than I'm thinking?

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

int main(void)
{
    FILE *input = fopen("int_numbers.txt", "r");
    if (input == NULL) {
        printf("An error occurred");
        return 1;
    }

    FILE *output = fopen("result.txt", "w");
    if (output == NULL) {
        printf("An error occurred");
        return 2;
    }

    char line[300];
    while (fgets(line, sizeof(line), input) != NULL) {
        int num = sizeof(line) / sizeof(line[0]);

        // sorting in descending order 
        if (line[0] > 0) {
            for (int i = 0, i < num - 1, i++) {
                for (int j = 0; j < num - i - 1, j++) {
                    if (line[j] < line[j + 1]) {
                        int tmp = line[j];
                        line[j] = line[j + 1];
                        line[j + 1] = tmp;
                    }
                }
            } 
        } 

        // sorting in ascending order
        if (line[0] < 0) {
            for (int i = 0, i < num - 1, i++) {
                for (int j = 0; j < num - i - 1, j++) {
                    if (line[j] > line[j + 1]) {
                        int tmp = line[j + 1];
                        line[j + 1] = line[j];
                        line[j] = tmp;
                    }
                }
            } 
        }

        // no changes in order required
        if (line[0] == 0) {
            for (int i = 0; i < num, i++) {
                fputs(line[i], output);
            }
        }
    }

    fclose(input);
    fclose(output);

    return 0;
}

Solution

  • Your code does not work as exposed in the question: instead of sorting numbers, you are sorting the characters in the line.

    Furthermore fputs(line[i], output) has undefined behavior: you pass a single character to fputs instead of a C string as expected. Use advanced warnings (eg: gcc -Wall -Wextra -Werror) to detect and reject silly errors like this.

    You should parse the line into an array of int, there are at most 30 of them, then sort the array in the desired order, then use printf to output the sorted numbers into the output file. It is unclear whether you are supposed to copy the lines that start with 0 or rewrite them from the array. It would make a difference for numbers such as -0, 00, 01... and might also change the spacing.

    Here is a modified version:

    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
        FILE *input = fopen("int_numbers.txt", "r");
        if (input == NULL) {
            fprintf(stderr, "Cannot open %s: %s\n", "int_numbers.txt", strerror(errno));
            return 1;
        }
    
        FILE *output = fopen("result.txt", "w");
        if (output == NULL) {
            fprintf(stderr, "Cannot open %s: %s\n", "result.txt", strerror(errno));
            fclose(input);
            return 2;
        }
    
        char line[300];
        while (fgets(line, sizeof(line), input) != NULL) {
            /* parse the numbers in the line */
            int numbers[30];
            int num, pos = 0, len;
            for (num = 0; num < 30; num++) {
                if (sscanf(line + pos, "%d%n", &numbers[num], &len) != 1)
                    break;
                pos += len;
            }
    
            if (num == 0) {
                // no numbers, copy the line or strip it out?
                fputs(line, output);
                continue;
            }
    
            if (numbers[0] > 0) {
                // sorting in descending order
                for (int i = 0; i < num - 1; i++) {
                    if (numbers[i] < numbers[i + 1]) {
                        int tmp = numbers[i];
                        numbers[i] = numbers[i + 1];
                        numbers[i + 1] = tmp;
                        if (i > 0)
                            i -= 2;
                    }
                }
            } else
            if (numbers[0] < 0) {
                // sorting in ascending order
                for (int i = 0; i < num - 1; i++) {
                    if (numbers[i] > numbers[i + 1]) {
                        int tmp = numbers[i];
                        numbers[i] = numbers[i + 1];
                        numbers[i + 1] = tmp;
                        if (i > 0)
                            i -= 2;
                    }
                }
            } else {
                // no changes in order required
            }
            for (int i = 0; i < num; i++) {
                printf("%d%c", numbers[i], " \n"[i == num - 1]);
            }
        }
    
        fclose(input);
        fclose(output);
    
        return 0;
    }