June 13, 2021

C Piscine C 04

Piscine C 03 ex00 (ft_strlen)

Задание:

• Create a function that counts and returns the number of characters in a string. • Here’s how it should be prototyped :

int ft_strlen(char *str);

• Создайте функцию, которая считает и возвращает количество символов в строке. • Вот как это должно быть объявлено:

int ft_strlen(char *str);

Решение 1

int    ft_strlen(char *str)
{
    int i;

    i = 0;
    while (str[i] != '\0')
        i++;
    return (i);
}

Решение 2

int    ft_strlen(char *str)
{
    int i;

    i = 0;
    while (*(str + i))
        i++;
    return (i);
}

Решение 3

int    ft_strlen(char *str)
{
    int n;

    n = 0;
    while (*str != '\0')
    {
        str++;
        n++;
    }
    return (n);
}

Объяснения + проверка int main

Команда для компиляции и одновременного запуска:

gcc -Wall -Werror -Wextra названиефайла.c && chmod +x ./a.out && ./a.out

Piscine C 03 ex01 (ft_putstr)

Задание:

• Create a function that displays a string of characters on the standard output. • Here’s how it should be prototyped :

void ft_putstr(char *str);

• Создайте функцию, которая отображает строку символов в стандартном выводе. • Вот как это должно быть объявлено:

void ft_putstr(char *str);

Решение 1

void    ft_putstr(char *str)
{
    unsigned int    i;

    i = 0;
    while (*(str + i))
        i++;
    write(1, str, i);
}


/*        ИЛИ, тоже самое но, ТАК :
void    ft_putstr(char *str)
{
    unsigned int    i;
    i = 0;
    while (str[i])
        i++;
    write(1, str, i);
}
*/

Решение 2

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

void    ft_putstr(char *str)
{
    unsigned int    i;

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

/*        ИЛИ, тоже самое но, ТАК :
void    ft_putstr(char *str)
{
    unsigned int i;
    i = 0;
    while (str[i])
        ft_putchar(str[i++]);
}
*/

Решение 3

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

void    ft_putstr(char *str)
{
    while (*str != '\0')
    {
        ft_putchar(*str);
        str++;
    }
}

/*        ИЛИ, тоже самое но, ТАК :
void    ft_putstr(char *str)
{
    while (*str)
        ft_putchar(*str++);
}
*/

Объяснения + проверка int main

Команда для компиляции и одновременного запуска:

gcc -Wall -Werror -Wextra названиефайла.c && chmod +x ./a.out && ./a.out

Piscine C 03 ex02 (ft_putnbr)

Задание:

• Create a function that displays the number entered as a parameter. The function has to be able to display all possible values within an int type variable. • Here’s how it should be prototyped :

void ft_putnbr(int nb);

• For example: ft_putnbr(42) displays "42"

• Создайте функцию, которая отображает число, введенное в качестве параметра. Функция должна иметь возможность отображать все возможные значения в переменной типа int. • Вот как это должно быть объявлено:

void ft_putnbr(int nb);

• Например: ft_putnbr(42) displays "42"

Решение 1

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

void    ft_putnbr(int nb)
{
    int    temp;
    int    size;

    size = 1;
    if (nb < 0)
    {
        ft_putchar('-');
        nb = -nb;
    }
    if (nb == -2147483648)
    {
        ft_putchar('2');
        nb = 147483648;
    }
    temp = nb;
    while ((temp /= 10) > 0)
        size *= 10;
    temp = nb;
    while (size)
    {
        ft_putchar((char)((temp / size)) + 48);
        temp %= size;
        size /= 10;
    }
}

Решение 2

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

void    ft_putnbr(int n)
{
    if (n < 0)
    {
        n = -n;
        ft_putchar('-');
    }
    if (n >= 10)
        ft_putnbr(n / 10);
    ft_putchar((n % 10) + '0');
}

Решение 3

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

void    ft_putnbr(int nb)
{
    if (nb < 0)
    {
        nb = -nb;
        ft_putchar('-');
    }
    if (nb < 10)
        ft_putchar(nb + '0');
    else
    {
        ft_putnbr(nb / 10);
        ft_putnbr(nb % 10);
    }
}

Объяснения + проверка int main

Команда для компиляции и одновременного запуска:

gcc -Wall -Werror -Wextra названиефайла.c && chmod +x ./a.out && ./a.out

Piscine C 03 ex03 (ft_putnbr)

Задание:

• Write a function that converts the initial portion of the string pointed by str to its int representation

• The string can start with an arbitray amount of white space (as determined by isspace(3))

• The string can be followed by an arbitrary amount of + and - signs, - sign will change the sign of the int returned based on the number of - is odd or even.

• Finally the string can be followed by any numbers of the base 10.

• Your function should read the string until the string stop following the rules and return the number found until now.

• You should not take care of overflow or underflow. result can be undefined in that case.

• Here’s an example of a program that prints the atoi return value:

$>./a.out " ---+--+1234ab567"

-1234

• Напишите функцию, которая преобразует начальную часть строки, на которую указывает 'str', в ее представление 'int'

• Строка может начинаться с произвольного количества пробелов (как определено с помощью isspace (3))

• За строкой может следовать произвольное количество знаков '+' и '-', знак '-' изменит знак возвращаемого целого числа 'int' в зависимости от количества '-' нечетных или четных.

• Наконец, за строкой могут следовать любые числа с основанием 10(десятичные).

• Ваша функция должна читать строку до тех пор, пока она не перестанет следовать правилам и не вернет число, найденное до сих пор.

• Не стоит заботиться о переполнении или опустошении. В этом случае результат может быть неопределенным.

• Вот пример программы, которая печатает возвращаемое значение atoi:

$>./a.out " ---+--+1234ab567"

-1234

Решение 1

int    ft_atoi(char *str)
{
    int    sign;
    int    num;

    sign = 1;
    num = 0;
    while ((*str == ' ') || (*str == '\t') || (*str == '\n')
        || (*str == '\v') || (*str == '\f') || (*str == '\r'))
        str++;
    if (*str == '-')
        sign = -1;
    while ((*str == '-') || (*str == '+'))
        str++;
    while (*str >= '0' && *str <= '9')
    {
        num = (num * 10) + ((int)*str - '0');
        str++;
    }
    return (num * sign);
}

Решение 2

int            ft_atoi(char *str)
{
    int        v;
    int        n;

    n = 0;
    if (*str == '-')
    {
        str++;
        n = 1;
    }
    v = 0;
    while (*str != '\0')
    {
        if (*str >= '0' && *str <= '9')
            v = (v * 10) + (*str - '0');
        else
            return (0);
        str++;
    }
    return ((v > 0 && n) ? -v : v);
}

Решение 3

int    ft_atoi(char *str)
{
    int    x;
    int total;
    int is_negative;

    is_negative = 0;
    x = 0;
    total = 0;
    while (str[x] == ' ' || str[x] == '\n' || str[x] == '\r' || str[x] == '\f'
            || str[x] == '\t' || str[x] == '\v' || str[x] == '+')
        x++;
    if (str[x] == '-')
    {
        is_negative = 1;
        x++;
    }
    while ((str[x] == '-') || (str[x] == '+'))
        x++;
    while (str[x] >= '0' && str[x] <= '9')
    {
        total *= 10;
        total += ((int)str[x] - 48);
        x++;
    }
    if (is_negative)
        return (-total);
    else
        return (total);
}

Решение 4

int    ft_atoi(char *str)
{
    int    x;
    int total;
    int is_negative;

    is_negative = 0;
    x = 0;
    total = 0;
    while (str[x] == ' ' || str[x] == '\n' || str[x] == '\r' || str[x] == '\f'
            || str[x] == '\t' || str[x] == '\v' || str[x] == '+')
        x++;
    if (str[x] == '-')
    {
        is_negative = 1;
        x++;
    }
    while ((str[x] == '-') || (str[x] == '+'))
        x++;
    while (str[x] >= '0' && str[x] <= '9')
    {
        total *= 10;
        total += ((int)str[x] - 48);
        x++;
    }
    if (is_negative)
        return (-total);
    else
        return (total);
}

Объяснения + проверка int main

Команда для компиляции и одновременного запуска:

gcc -Wall -Werror -Wextra названиефайла.c && chmod +x ./a.out && ./a.out

Piscine C 04 ex04 (ft_putnbr_base)

Задание:

• Create a function that displays a number in a base system in the terminal. • This number is given in the shape of an int, and the radix in the shape of a string of characters. • The base-system contains all useable symbols to display that number : ◦ 0123456789 is the commonly used base system to represent decimal numbers ◦ 01 is a binary base system ; ◦ 0123456789ABCDEF an hexadecimal base system ; ◦ poneyvif is an octal base system. • The function must handle negative numbers. • If there’s an invalid argument, nothing should be displayed. Examples of invalid arguments : ◦ base is empty or size of 1; ◦ base contains the same character twice ; ◦ base contains + or - ; • Here’s how it should be prototyped :

void ft_putnbr_base(int nbr, char *base);

• Создайте функцию, которая отображает число в нужной базовой системе счисления на экране.

• В аргументах функции это число дается нам в форме целого числа, а система счисления дается нам - в виде 'строки символов'.

• Базовая система счисления содержит все используемые символы для отображения этого числа:

- 0123456789 - широко используемая базовая десятична система для представления десятичных чисел;

- 01 - двоичная базовая система;

- 0123456789ABCDEF шестнадцатеричная базовая система;

- poneyvif - это восьмеричная базовая система.

• Функция должна обрабатывать отрицательные числа.

• Если указан неверный аргумент, ничего не должно отображаться. Примеры неверных аргументов:

- Если база, отражающая систему счисления, пуста или имеет размер 1;

- Если база, отражающая систему счисления, содержит один и тот же символ дважды;

- Если база, отражающая систему счисления, содержит символы '+' или '-';

- и т. д.

void ft_putnbr_base(int nbr, char *base);

Решение 1

int    ft_atoi(char *str)
{
    int    x;
    int total;
    int is_negative;

    is_negative = 0;
    x = 0;
    total = 0;
    while (str[x] == ' ' || str[x] == '\n' || str[x] == '\r' || str[x] == '\f'
            || str[x] == '\t' || str[x] == '\v' || str[x] == '+')
        x++;
    if (str[x] == '-')
    {
        is_negative = 1;
        x++;
    }
    while ((str[x] == '-') || (str[x] == '+'))
        x++;
    while (str[x] >= '0' && str[x] <= '9')
    {
        total *= 10;
        total += ((int)str[x] - 48);
        x++;
    }
    if (is_negative)
        return (-total);
    else
        return (total);
}

Решение 2

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

static int    ft_check_base(char *base)
{
    int    i;
    int    z;

    i = 0;
    if (!base || !base[1])
        return (0);
    while (base[i])
    {
        if (!((base[i] >= '0' && base[i] <= '9') || (base[i] >= 'a' \
                && base[i] <= 'z') || (base[i] >= 'A' && base[i] <= 'Z')))
            return (0);
        z = i + 1;
        while (base[z])
        {
            if (base[i] == base[z])
                return (0);
            z++;
        }
        i++;
    }
    return (i);
}


int        ft_get_len_future_nbr(int nbr, int base_type)
{
    int    size;

    if (base_type)
    {
        size = 1;
        while ((nbr /= base_type) > 0)
            size++;
    }
    return (size);
}

void    ft_conv_nbr(int nbr, int length, char *base, int base_type)
{
    int        i;
    int        n[length];

    i = 0;
    while (nbr)
    {
        n[i] = nbr % base_type;
        nbr /= base_type;
        i++;
    }
    while (i > 0)
        ft_putchar(base[n[--i]]);
    
}


void    ft_putnbr_base(int nbr, char *base)
{
    int        base_type;

    if ((base_type = ft_check_base(base)))
    {
        if (nbr < 0)
        {
            nbr = -nbr;
            ft_putchar('-');
        }
        ft_conv_nbr(nbr, ft_get_len_future_nbr(nbr, base_type), base, base_type);
    }
}

Решение 3

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


int        ft_check_base(char *base)
{
    int    i;
    int    z;

    i = 0;
    z = 0;
    if (base[0] == '\0' || base[1] == '\0')
        return (0);
    while (base[i])
    {
        z = i + 1;
        if (base[i] == '+' || base[i] == '-')
            return (0);
        if (base[i] < 32 || base[i] > 126)
            return (0);
        while (base[z])
        {
            if (base[i] == base[z])
                return (0);
            z++;
        }
        i++;
    }
    return (i);
}

void    ft_putnbr_base(int nbr, char *base)
{
    int    base_type;
    int    nbr_final[100];
    int    i;

    i = 0;
    if ((base_type = ft_check_base(base)))
    {
        if (nbr < 0)
        {
            nbr = -nbr;
            ft_putchar('-');
        }
        while (nbr)
        {
            nbr_final[i] = nbr % base_type;
            nbr = nbr / base_type;
            i++;
        }
        while (--i >= 0)
            ft_putchar(base[nbr_final[i]]);
    }
}

Решение 4

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


static int    ft_strlen(char *str)
{
    int len;

    len = 0;
    while (*str++ != '\0')
    {
        len++;
    }
    return (len);
}

static void    ft_putnbr_base_n(int nbr, char *base, int n)
{
    if (nbr < 0)
    {
        ft_putchar('-');
        if (nbr == -2147483648)
        {
            ft_putnbr_base_n(2, base, n);
            ft_putnbr_base_n(147483648, base, n);
        }
        else
            ft_putnbr_base_n(-nbr, base, n);
    }
    else if (nbr < n)
        ft_putchar(base[nbr]);
    else
    {
        ft_putnbr_base_n(nbr / n, base, n);
        ft_putchar(base[nbr % n]);
    }
}

static int    ft_strchar(char *str, char to_find)
{
    while (*str != '\0')
        if (to_find == *str++)
            return (1);
    return (0);
}

static int    ft_check_base(char *base, int n)
{
    while (n)
    {
        if (base[n] == '+' || base[n] == '-')
            return (0);
        if (ft_strchar(base + n + 1, base[n]))
            return (0);
        --n;
    }
    return (1);
}

void        ft_putnbr_base(int nbr, char *base)
{
    int        base_len;

    base_len = ft_strlen(base);
    if (base && (base_len > 1) && ft_check_base(base, base_len))
        ft_putnbr_base_n(nbr, base, base_len);
}

Объяснения + проверка int main

Команда для компиляции и одновременного запуска:

gcc -Wall -Werror -Wextra названиефайла.c && chmod +x ./a.out && ./a.out

Piscine C 04 ex05 (ft_atoi_base)

Задание:

• Write a function that converts the initial portion of the string pointed by str to int representation.

• str is in a specific base given as a second parameter.

• excepted the base rule, the function should work exactly like ft_atoi.

• If there’s an invalid argument, the function should return 0. Examples of invalid arguments :

◦ base is empty or size of 1;

◦ base contains the same character twice ;

◦ base contains + or - or whitespaces;

• Here’s how it should be prototyped :

int ft_atoi_base(char *str, char *base);

• Напишите функцию, которая преобразует начальную часть строки, на которую указывает 'str', в целое число 'int'.

• Строка символов 'str' представляет собой число в определенной системе счисления, заданной во втором параметре.

• За исключением базового правила, функция должна работать точно так же, как и функция 'ft_atoi'.

• Если указан неверный аргумент, функция должна вернуть 0. Примеры неверных аргументов:

◦ Если база, отражающая систему счисления, пуста или имеет размер 1;

◦ Если база, отражающая систему счисления, содержит один и тот же символ дважды;

◦ Если база, отражающая систему счисления, содержит символы '+' или '-';

int ft_atoi_base(char *str, char *base);

Решение 1

int        ft_ctoi(char c)
{
    if (c >= '0' && c <= '9')
        return (c - '0');
    if (c >= 'A' && c <= 'F')
        return (c - 'A' + 10);
    if (c >= 'a' && c <= 'f')
        return (c - 'a' + 10);
    return (-1);
}



int        ft_pow(int nb, int power)
{
    int    result;

    result = 1;
    if(power < 0)
        return (0);
    if(power == 0)
        return (1);
    while (power--)
        result *= nb;
    return (result);
}



int        ft_check_base(char *base)
{
    int    i;
    int    z;

    i = 0;
    z = 0;
    if (!base || !base[1])
        return (0);
    while (base[i])
    {
        z = i + 1;
        if (!((base[i] >= '0' && base[i] <= '9') || (base[i] >= 'a' \
                && base[i] <= 'z') || (base[i] >= 'A' && base[i] <= 'Z')))
            return (0);
        while (base[z])
        {
            if (base[i] == base[z])
                return (0);
            z++;
        }
        i++;
    }
    return (i);
}



int        ft_atoi_base(char *str, char *base)
{
    int        num;
    int        negative;
    int        i;
    int        pow;
    int        base_type;

    negative = 1;
    i = 0;
    if((base_type = ft_check_base(base)))
    {
        if (*str == '-')
        {
            i++;
            negative = -1;
        }
        while (str[i])
            i++;
        pow = 0;
        num = 0;
        while (--i >= 0)
        {
            if ((ft_ctoi(str[i]) != -1) && (ft_ctoi(str[i]) < base_type))
                num += ft_ctoi(str[i]) * ft_pow(base_type, pow++);
        }
        return (num * negative);
    }
    return (0);
}

Решение 2

static int    ft_isspace(int c)
{
    return (c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'
        || c == ' ');
}

static int    ft_strlen(char *str)
{
    int        i;

    i = 0;
    while (str[i])
        i++;
    return (i);
}

static int    ft_find_char(char c, char *str)
{
    int i;

    i = 0;
    while (str[i] && str[i] != c)
        i++;
    return (i);
}

int            ft_atoi_base(char *str, char *base)
{
    int        result;
    int        neg;
    int        base_len;

    result = 0;
    base_len = ft_strlen(base);
    if (base_len < 2)
        return (0);
    while (ft_isspace(*str))
        str++;
    neg = *str == '-';
    str += (*str == '+' || *str == '-') ? 1 : 0;
    while (ft_find_char(*str, base) < base_len)
        result = result * base_len - ft_find_char(*str++, base);
    return (neg ? result : -result);
}

Решение 3

int        is_pr3(char c)
{
    return (c >= 32 && c <= 126);
}

int        is_space3(char c)
{
    return ((c >= 9 && c <= 13) || c == ' ');
}

int        validate_base3(char *base)
{
    char    *ptr;
    int        i;
    int        vals[95];

    ptr = base;
    i = -1;
    while (i++ < 95)
        vals[i] = 0;
    i = 0;
    while (*ptr)
    {
        if (!is_pr3(*ptr))
            return (0);
        if (*ptr == '+' || *ptr == '-')
            return (0);
        if (vals[(*ptr) - 32])
            return (0);
        vals[(*ptr) - 32] = 1;
        i++;
        ptr++;
    }
    if (i < 2)
        return (0);
    return (i);
}

int        parse_positive(char *str, char *base, int basen)
{
    char    *ptr;
    int        i;
    int        v;

    v = 0;
    while (*str)
    {
        i = 0;
        ptr = base;
        while (*ptr)
        {
            if (*str == *ptr)
                break ;
            i++;
            ptr++;
        }
        if (i >= basen)
            break ;
        v *= basen;
        v -= i;
        str++;
    }
    return (v);
}

int        ft_atoi_base(char *str, char *base)
{
    int        basen;
    int        v;
    int        is_positive;

    if (!(basen = validate_base3(base)))
        return (0);
    is_positive = 0;
    while (is_space3(*str))
        str++;
    if (*str == '+' || *str == '-')
    {
        is_positive = -1;
        if (*str == '+')
            is_positive = 1;
        str++;
    }
    v = parse_positive(str, base, basen);
    v *= -(is_positive + !is_positive);
    return (v);
}

Объяснения + проверка int main

Команда для компиляции и одновременного запуска:

gcc -Wall -Werror -Wextra названиефайла.c && chmod +x ./a.out && ./a.out