728x90
1. 프로젝트 구조
mandatory part만 진행했으며 전체적인 구조는 아래와 같다.
📦ft_printf
┣ 📂includes
┃ ┗ 📜ft_printf.h
┣ 📂libft
┃ ┣ 📜ft_strlen.c
┃ ┣ 📜libft.h
┃ ┗ 📜Makefile
┣ 📂srcs
┃ ┣ 📜ft_checkbase.c
┃ ┣ 📜ft_formats.c
┃ ┣ 📜ft_printbase.c
┃ ┣ 📜ft_printf.c
┃ ┗ 📜ft_printstr.c
┣ 📜Makefile
2. 프로젝트 구현
libft 사용함수는 ft_strlen만 사용했고 사용하는 함수에 맞게 libft.h와 Makefile을 수정했다.
- ft_printf.h
#ifndef FT_PRINTF_H
# define FT_PRINTF_H
# include <stdarg.h>
# include <unistd.h>
# include "../libft/libft.h"
int ft_printf(const char *str, ...);
int ft_parsing(va_list args, const char format);
int ft_formats(va_list ap, const char *format);
char *base_type(const char type);
int ft_checkbase(va_list ap, const char format);
int ft_printi(int n, const char *base);
int ft_printu(unsigned int n, const char *base);
int ft_printp(unsigned long long n, const char *base);
void ft_printbase(unsigned long long num, const char *base);
int ft_printchar(int chr);
int ft_printstr(char *str);
#endif
- ft_printf.c
해당 함수에서는 입력을 받고 결과를 return하는 기능으로 구현했다. va_list 가변 인자 포인터 변수를 args라는 이름으로 선언하고, va_start(args, format)을 이용해 가변 인자를 가리키게 했다.
int ft_printf(const char *format, ...)
{
va_list args;
int print_length;
va_start(args, format);
print_length = ft_formats(args, format);
va_end(args);
return (print_length);
}
- ft_formats.c
이후 ft_fotmats에서 ft_parsing 함수를 이용해 문자열을 파싱하고 문자열의 수를 반환하도록 했다.
int ft_parsing(va_list args, const char format)
{
int print_length;
print_length = 0;
if (format == '%')
print_length += write(1, "%", 1);
else if (format == 'c')
print_length += ft_printchar(va_arg(args, int));
else if (format == 's')
print_length += ft_printstr(va_arg(args, char *));
else
print_length += ft_checkbase(args, format);
return (print_length);
}
int ft_formats(va_list ap, const char *format)
{
int i;
int print_length;
i = 0;
print_length = 0;
while (format[i])
{
if (format[i] == '%')
{
print_length += ft_parsing(ap, format[i + 1]);
i++;
}
else
print_length += write(1, (format + i), 1);
i++;
}
return (print_length);
}
- ft_checkbase.c
ft_checkbase에서 서식지정자에 맞는 베이스를 찾을 수 있도록 해주었다. 그 후 서식지정자에 맞게 d, i, u, x, X, p에 따라 출력할 수 있도록 ft_printbase를 해준다.
- ft_printbase.c
write() 함수를 써서 출력하고 길이를 반환하는 기능을 한다.
- ft_printstr.c
서식지정자 c와 s의 출력을 처리하는 부분이다. 서식지정자 s의 경우, NULL값을 때 (null)이 출력되도록 하고 반환 값은 6으로 처리해주었다.
- Makefile
- Makefile은 '변수명 = 값'으로 변수를 선언 후 값을 저장해서 사용할 수 있다. 이후 변수를 사용할 때는 $(변수명)처럼 이용해서 사용한다.
- $@ : 현재의 타겟명
- $^ : 현재 타겟의 의존성
- $? : 현재의 목표 파일보다 더 최근에 갱신된 파일 이름
- $< : 현재의 목표 파일보다 더 최근에 갱신된 파일 이름
- .PHONY: 실행 규칙을 위한 타겟명으로 사용하기 위한 것으로 타겟명으로 사용하는 단어가 파일명으로 있을 경우 충돌이 발생하는데, 이때 .PHONY에 타겟명을 명시하게되면 프로그램이 정상적으로 동작하게 된다.
- @ : 명령어와 명령의 실행 결과를 출력하지 않는다.
- -C dir : dir로 우선 이동할 수 있게된다. 순환 make에서 사용하게 된다.
NAME = libftprintf.a
CC = gcc
CFLAGS = -Wall -Wextra -Werror
AR = ar
ARFLAGS = rcs
RM = rm -rf
INCDIR = ./includes
LIBFT = ./libft
SRCS = ./srcs/ft_printf.c \
./srcs/ft_formats.c \
./srcs/ft_checkbase.c \
./srcs/ft_printbase.c \
./srcs/ft_printstr.c \
OBJS = $(SRCS:.c=.o)
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
$(NAME) : $(OBJS)
@make -C $(LIBFT)
@cp $(LIBFT)/libft.a $(NAME)
@ar rcs $@ $?
all : $(NAME)
clean :
$(RM) $(OBJS)
@make clean -C $(LIBFT)
fclean : clean
$(RM) $(NAME)
@make fclean -C $(LIBFT)
re: clean all
.PHONY: all clean fclean re
3. 사용한 테스터
728x90
반응형
'42 SEOUL > 1_ft_printf' 카테고리의 다른 글
[42Seoul/ft_printf] 서식지정자 (format specifier) (0) | 2022.04.19 |
---|---|
[42Seoul/ft_printf] 가변인자(variable argument) (0) | 2022.04.18 |
[42Seoul/ft_printf] 프로젝트 소개 (0) | 2022.04.18 |
댓글