ℹ️ Uma Biblioteca estática em C com funções padrão recodificadas
125/100 ✅
- O que é Libft?
- Requisitos
- Funções
- Makefile
- Como funciona?
- Como eu uso a Biblioteca?
- Como eu testo?
- 42 Cursus
- Autor
O Primeiro projeto na 42. Consiste em uma biblioteca estática em C com funções padrão da linguagem recodificadas que rodam e compilam usando um Makefile. A biblioteca pode ser usada de apoio em projetos futuros, uma vez que não é permitido o uso das funções originais. Uma vez que tenha terminado o projeto, você pode (e deve) incluir mais funções à sua Libft. Por exemplo, agora os projetos get_next_line e ft_printf são parte da minha biblioteca.
O projeto é dividio em três partes - Parte I, Parte II e Bônus.
Nessa primeira parte, você deve recodificar um conjunto de funções da libc, como definidas em seu manual (man). Suas funções precisam apresentar o mesmo protótipo e compartamento das originais. Além disso o nome das funções devem apresenar o prefixo “ft_”. Por exemplon, a strlen se torna ft_strlen. **ft_ vem de forty-two(42).
• isalpha • isdigit • isalnum • isascii • isprint • strlen • memset • bzero • memcpy • memmove • strlcpy • strlcat • toupper • tolower • strchr • strrchr • strncmp • memchr • memcmp • strnstr • atoi • calloc • strdup
Nessa segunda parte, você deve codar um punhado de funções que ou não estão inclusas na libc ou foram incluídas de uma outra forma. Algumas dessas funções podem ser úteis para escrever as funções da parte I.
• substr • strjoin • strtrim • split • itoa • strmapi • striteri • putchar_fd • putstr_fd • putendl_fd • putnbr_fd
Na parte Bônus, você deve codificar funções para manipulação de listas encadeadas.
• lstnew • lstadd_front • lstsize • lstlast • lstadd_back • lstdelone • lstclear • lstiter • lstmap
Cada função dever ter no máximo 25 linhas, não contando suas próprias chaves '{}'.
Cada linha deve ter no máximo 80 colunas de largura, comentários incluídos.
Uma função pode ter no máximo 4 parâmetros definidos.
Não podem ser declaradas mais que 5 variáveis por função.
Não é permitido o uso de: for , do...while , switch , case , goto ,
operadores ternários como `?' e VLAs - Matrizes de comprimento variável.
A norminette (como chamamos a norma na 42) é feita em python e é open source.
O repositório está disponível em https://github.com/42School/norminette
Além da norma padrão, o projeto tem alguns requisitos próprios
É proibido declarar variáveis globais.
Usar o comando libtool para criar a biblioteca é proibido.
O Makefile deve compilar com as flags -Wall, -Wextra e -Werror
Essas são as funções presentes na minha Libft atualmente - algumas não fazem parte do subject - já que podemos posteriormente adicionar funções para usar em outros projetos.
• ft_isalpha - checa se é um caractere alfabético.
• ft_isdigit - checa se é um digito (0 a 9).
• ft_isalnum - checa se é um caractere alfanumérico.
• ft_isascii - checa se é um caractere que faz parte da tabela ASCII tradicional.
• ft_isprint - checa se é um caractere printável.
• ft_toupper - converte o caractere para maiúsculo.
• ft_tolower - converte o caractere para minúsculo.
• ft_memset - enche o bloco de memória com um mesmo byte.
• ft_strlen - calcula o tamanho de uma string.
• ft_bzero - preenche uma string com zero.
• ft_memcpy - copia uma área de memória.
• ft_memmove - copia uma área de memória.
• ft_strlcpy - copia uma string para um tamanho especificado.
• ft_strlcat - concatena uma string para um um tamanho especificado.
• ft_strchr - localiza a primeira ocorrência de um caractere em uma string.
• ft_strrchr - localiza a última ocorrência de um caractere em uma string.
• ft_strncmp - compara duas strings.
• ft_memchr - checa um bloco de memória em busca de um caractere.
• ft_memcmp - compara blocos de memória.
• ft_strnstr - localiza uma substring dentro de uma string.
• ft_strdup - cria uma duplicata da string passada como parâmetro.
• ft_atoi - converte uma string para um inteiro.
• ft_calloc - alloca memória e seta o valor de todos os bytes para 0.
• ft_substr - retorna uma substring de uma string.
• ft_strjoin - retorna uma string que é a junção das duas strings passadas como parâmetro.
• ft_strtrim - Corta o início e fim de uma string quando achada a sequência de caracteres passada.
• ft_split - separa uma string em várias substrings delimitadas por um caractere.
• ft_itoa - converte um número em string.
• ft_strmapi - aplica uma função a cada caractere de uma string.
• ft_striteri - aplica uma função a cada caractere de uma string.
• ft_putchar_fd - da como output um caratere para um file descriptor.
• ft_putstr_fd - da como output uma string para um file descriptor.
• ft_putendl_fd - da como output uma string para um file descriptor, seguido por uma nova linha.
• ft_putnbr_fd - da como output um número para um file descriptor.
• ft_lstnew - cria um novo elemento para a lista.
• ft_lstadd_front - adiciona um elemento no início de uma lista.
• ft_lstsize - counta o número de elementos em uma lista.
• ft_lstlast - retorna o último elemento de uma lista.
• ft_lstadd_back - adiciona um elemento ao fim de uma lista.
• ft_lstclear - deleta e da free em uma lista.
• ft_lstiter - aplica uma função a cada elemento de uma lista.
• ft_lstmap - aplica uma função a cada elemento de uma lista.
• get_next_line - lê qualquer arquivo válido linha por linha.
• ft_printf - imprime uma string formatada em alguma saída do sistema.
• ft_argument_c - printa um char no stdout.
• ft_arguments_d_i - printa um número inteiro no stdout.
• ft_argument_p - printa um endereço de memória (hexadecimal) no stdout.
• ft_argument_percent - printa um sinal de porcentagem no stdout.
• ft_argument_s - printa uma string no stdout.
• ft_argument_u - printa um unsigned int no stdout.
• ft_arguments_x - printa um número hexadecimal no stdout.
• ft_decimal_length - retorna o tamanho de um número decimal.
• ft_free_ptr - libera a memória e seta seu valor para nulo.
• ft_decimal_converter_to_hex - converte um número decimal em hexadecimal
• ft_hex_length - retorna o tamanho de um número hexadecimal.
• ft_print_reversed_str - printa uma string ao contrário.
• ft_count_occurrences - retorna o número de ocorrências de um char em uma string.
ℹ️ Uma ferramenta de automacão para rodar e compilar seus programas com maior eficiência.
Um Makefile define uma série de tarefas para serem executadas em shell script. Essas tarefas são escritas em um target nesse formato:
target: pré-requisitos
<TAB> receita
como em:
fclean: clean
@echo "$(NAME): $(RED)$(NAME) was deleted$(RESET)"
${REMOVE} ${NAME}
@echo
A receita (os comandos @echo e por ai vai) para o target fclean só vai ser executada quando o target clean (o pré-requisito) for executado. Um target funciona sem pré-requisito também:
clean:
@echo "\n$(NAME): $(RED)object files were deleted$(RESET)"
${REMOVE} ${OBJS} ${BONUS_OBJS}
@echo
Como você pode ver, há algumas variáveis dentro da receita. As variáveis no Makefile podem ser criadas e atribuídas assim:
GREEN = \033[0;32m
RED = \033[0;31m
RESET = \033[0m
CC = clang
FLAGS = -Wall -Werror -Wextra
Para usar o valor da variável apenas digite o nome com o sinal de $:
@echo "$(NAME): $(RED)$(NAME) was deleted$(RESET)"
Usar variáveis faz o seu Makefile mais legível e facil de alterar.
Não é necessário que o target seja um arquivo como em $(NAME). Pode ser apenas o nome da receita, como acima. Chamamos esses targets de phony targets.
Se você tiver um arquivo com o exato nome da sua phony target, as coisas podem ficar um pouco estranhas.
Para proteger seu Makefile disso, apenas use phony e o nome de todos os seus phony targets usados:
.PHONY: all clean fclean re bonus
Aqui na 42, o subject diz que:
Your Makefile must at least contain the rules $(NAME), all, clean, fclean and re.
As regras são target, é só nomear como $(NAME), all, clean, fclean e re.
A regra $(NAME), nesse caso, deveria criar a biblioteca estática $(NAME).
all é usado para o principal objetivo do seu Makefile: criar a biblioteca estática $(NAME).
clean remove os objetos criados para fazer a biblioteca.
fclean remove os objetos criados para fazer a biblioteca e a biblioteca estática $(NAME).
re apenas remove os objetos criados para fazer a biblioteca e a biblioteca estática $(NAME), para então recompilar tudo.
Você pode rodar uma regra do seu Makefile nesse modelo:
make $(nome_regra)
Assim:
make clean
No caso do target all, só digite make
make
Escolha uma cor, adicone como variável e use no seu Makefile:
BLACK ="\[\033[0;30m\]"
RED ="\[\033[0;31m\]"
GREEN ="\[\033[0;32m\]"
YELLOW ="\[\033[0;33m\]"
BLUE ="\[\033[0;34m\]"
PURPLE ="\[\033[0;35m\]"
CYAN ="\[\033[0;36m\]"
WHITE ="\[\033[0;37m\]"
RESET ="\033[0m"
Você pode usar assim:
@echo "$(NAME): $(RED)$(NAME) was deleted$(RESET)"
E então "$(NAME) was deleted" será printada em vermelho no terminal.
Maneiro, né?
Lembre de resetar a cor quando terminar de usar uma cor, de contrário o terminal ficará da cor da última cor usada.
O funcionamento da biblioteca pode ser explicado apenas desmembrando o Makefile. As funções da biblioteca estão todas em arquivos .c. Estes arquivos são compilados em objetos (.o) para serem depois inseridos na biblioteca, fazemos isso apenas compilando com as flags -c e -o.
clang -c exemplo1.c -o exemplo1.o
clang -c exemplo2.c -o exemplo2.o
clang -c exemplo3.c -o exemplo3.o
clang -c exemplo4.c -o exemplo4.o
E então usando o comando ar rcs para criar a biblioteca com todos os objetos.
ar rcs libft.a exemplo1.o exemplo2.o exemplo3.o exemplo4.o
Com todos esses arquivos transformados em objetos não precisamos compilar todo o código de novo em caso de alguma alteração, apenas os arquivos modificados seriam recompilados.
O Makefile é usado para automatizar o processo, uma vez que há pelo menos 40 arquivos a ser compilados em objeto e depois linkados na biblioteca.
O objetivo é criar uma bilioteca chamada libft.a feita com os arquivos fonte.Para criar a biblioteca, clone o projeto:
git clone https://github.com/augustobecker/libft libft
Entre no repositório:
cd libft
Rode o comando Make (para executar o Makefile que vai compilar o código fonte e criar a biblioteca):
make
Você deve ver um arquivo libft.a e alguns arquivos objeto (.o).
Agora, para limpar tudo (remover os arquivos .o), use make clean:
make clean
Agora, só precisa adicionar esse cabeçalho nos seus arquivos .c e usar as funções da Libft:
#include "libft.h"
Se tentar compilar seus arquivos com clang usando clang examplo.c vai receber um erro de undefined symbol para as funções da Libft.
Você deve mostrar qual é a biblioteca:
clang exemplo.c libft.a
É isso, agora basta executar com ./a.out
Para testar o código vamos usar um Tester para a Libft feito pelo @jgambard. Há vários outros bons testers mas hoje vou cobrir apenas esse.
Para testar o código desse repositório: Clone o repositório e entre nele:
git clone https://github.com/augustobecker/libft libft
cd libft/
Agora, clone o Libft Tester do @jgambard
git clone https://github.com/Tripouille/libftTester libftTester
Entre na pasta do Tester e rode o teste mandatório e então o bônus:
cd libftTester
make m
make b
Se você fez tudo corretamente, deve ver algo como isso:
A 42 é uma iniciativa educacional global que propõe uma nova forma de aprender tecnologia: sem professores, sem salas de aula, estudantes aprendendo com seus colegas estudantes (Aprendizado peer to peer), com uma metodologia que desenvolve habilidades de computação e da vida. Sem mencionar que é completamente gratuita e aberta para todos, sem pré-requisitos.
As admissões na 42 são diferentes de outras escolas. Usamos um processo de admissão baseado em mérito. O passo final no processo é a Piscina - parte parte do processo seletivo que requer 4 semanas de código intenso e imersivo. Não é necessário experiência anterior em programação.
Você pode conferir mais sobre o processo de admissão no site da 42sp: https://www.42sp.org.br
ou no meu repositório do github: 42 Piscine
Para ver outros projetos da 42 desenvolvidos por mim, clique aqui: 42 Cursus