cbashshellcommand-line-arguments

How to sort command line arguments in ASCII order in C language


I am struggling with a an exercise, I'm currently doing a pool in an affiliate school with 42 called 1337 (In case you're curious about why).

The use of printf is definitely forbidden and is considered as cheat, the only function I'm allowed to use is write(), from the unistd.h library #include

I've done other exercises, that I'm gonna link to you, one that displays arguments normally, and one that displays them in reverse order.

The code below literally just prints the arguments

#include <unistd.h>

void        ft_putchar(char ch)
{
    write(1, &ch, 1);
}

void        ft_print_params(int argc, char *argv)
{
    int i;

    i = 0;
    while (i < argc)
    {
        while (argv[i] != '\0')
        {
            ft_putchar(argv[i]);
            i++;
        }
        i++;
    }
}

int         main(int argc, char **argv)
{
    int i;

    i = 1;
    while (i < argc)
    {
        ft_print_params(argc, argv[i]);
        ft_putchar('\n');
        i++;
    }
    return (0);
}

The program below, prints the arguments in reverse order.

#include <unistd.h>

void        ft_putchar(char ch)
{
    write(1, &ch, 1);
}

void        ft_print_params(char *argv)
{
    int i;

    i = 0;
    while (argv[i] != '\0')
    {
        ft_putchar(argv[i]);
        i++;
    }
}

int         main(int argc, char **argv)
{
    int i;

    i = argc;
    if (1)
    {
        while (i > 1)
        {
            ft_print_params(argv[i - 1]);
            ft_putchar('\n');
            i--;
        }
    }
    return (0);  
}

So I would love if someone could help me out, with either ideas, or maybe some code, and with some explanations if possible.

Thanks.


Solution

  • You could write a function to perform a simple insertion sort on an array of char * in situ:

    #include <string.h>
    
    void ft_sort_strings(int num, char **s)
    {
        int i, j;
        for (i = 1; i < num; i++)
        {
            for (j = i; j > 0 && strcmp(s[j-1], s[j]) > 0; j--)
            {
                char *temp = s[j-1];
                s[j-1] = s[j];
                s[j] = temp;
            }
        }
    }
    

    Then, call it from main to sort argv, skipping the first element:

        ft_sort_strings(argc - 1, argv + 1);
    

    Then you just need to loop through the arguments and print them as you did before.

    If you are not allowed to use strcmp from the standard library, it is easy enough to replace it with your own ft_strcmp:

    int ft_strcmp(const char *a, const char *b)
    {
        unsigned char ac, bc;
        /* interpret chars as unsigned char for compatibility with strcmp() */
        while (ac = *(const unsigned char *)a,
               bc = *(const unsigned char *)b,
               ac && ac == bc)
        {
            a++;
            b++;
        }
        return (ac > bc) - (ac < bc);
    }