├── get_next_line ├── text.txt ├── test.sh ├── main.c ├── get_next_line.h ├── subject.en.txt ├── README.md ├── get_next_line.c └── old_gnl │ ├── get_next_line.c │ └── get_next_line_ort.c ├── .ft_printf.c.swp ├── ft_printf ├── diff.sh ├── test.sh ├── subject.en.txt ├── README.md ├── ft_printf.c ├── main.c └── old_printf │ └── ft_printf.c ├── inter ├── subject.en.txt └── inter.c ├── union └── subject.en.txt └── README.md /get_next_line/text.txt: -------------------------------------------------------------------------------- 1 | aaaa 2 | bbbbb 3 | ccccc 4 | dddd -------------------------------------------------------------------------------- /.ft_printf.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenkim18/Exam_Rank_02/HEAD/.ft_printf.c.swp -------------------------------------------------------------------------------- /ft_printf/diff.sh: -------------------------------------------------------------------------------- 1 | gcc -Wall -Wextra -Werror ori.c -o ori.out 2 | gcc -Wall -Wextra -Werror cus.c ft_printf.c -o cus.out 3 | 4 | chmod 775 ./ori.out ./cus.out 5 | 6 | ./ori.out >> ori.txt 7 | ./cus.out >> cus.txt 8 | 9 | diff -d ori.txt cus.txt 10 | -------------------------------------------------------------------------------- /ft_printf/test.sh: -------------------------------------------------------------------------------- 1 | gcc -Wall -Werror -Wextra ft_printf.c main.c -o ft_printf 2 | ./ft_printf > yy 3 | cat -e yy > y 4 | gcc -Wall -Werror -Wextra -D REAL main.c -o printf 5 | ./printf | cat -e > r 6 | diff -y --suppress-common-lines r y 7 | rm -rf yy y r ft_printf printf -------------------------------------------------------------------------------- /get_next_line/test.sh: -------------------------------------------------------------------------------- 1 | gcc -Wall -Werror -Wextra get_next_line.c main.c -o get_next_line 2 | ./get_next_line < get_next_line.c > yours_.res 3 | cat -e yours_.res > yours.res 4 | cat -e < get_next_line.c > original.res 5 | diff -y --suppress-common-line original.res yours.res 6 | rm -rf original.res yours_.res yours.res get_next_line 7 | -------------------------------------------------------------------------------- /get_next_line/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "get_next_line.h" 5 | 6 | int main(void) 7 | { 8 | int r; 9 | char *line; 10 | 11 | line = NULL; 12 | printf("===================================================\n"); 13 | while ((r = get_next_line(&line)) > 0) 14 | { 15 | printf("%s\n", line); 16 | free(line); 17 | line = NULL; 18 | } 19 | printf("%s", line); 20 | free(line); 21 | line = NULL; 22 | printf("===================================================\n"); 23 | } 24 | -------------------------------------------------------------------------------- /inter/subject.en.txt: -------------------------------------------------------------------------------- 1 | Assignment name : inter 2 | Expected files : inter.c 3 | Allowed functions: write 4 | -------------------------------------------------------------------------------- 5 | 6 | Write a program that takes two strings and displays, without doubles, the 7 | characters that appear in both strings, in the order they appear in the first 8 | one. 9 | 10 | The display will be followed by a \n. 11 | 12 | If the number of arguments is not 2, the program displays \n. 13 | 14 | Examples: 15 | 16 | $>./inter "padinton" "paqefwtdjetyiytjneytjoeyjnejeyj" | cat -e 17 | padinto$ 18 | $>./inter ddf6vewg64f gtwthgdwthdwfteewhrtag6h4ffdhsd | cat -e 19 | df6ewg4$ 20 | $>./inter "nothing" "This sentence hides nothing" | cat -e 21 | nothig$ 22 | $>./inter | cat -e 23 | $ 24 | -------------------------------------------------------------------------------- /union/subject.en.txt: -------------------------------------------------------------------------------- 1 | Assignment name : union 2 | Expected files : union.c 3 | Allowed functions: write 4 | -------------------------------------------------------------------------------- 5 | 6 | Write a program that takes two strings and displays, without doubles, the 7 | characters that appear in either one of the strings. 8 | 9 | The display will be in the order characters appear in the command line, and 10 | will be followed by a \n. 11 | 12 | If the number of arguments is not 2, the program displays \n. 13 | 14 | Example: 15 | 16 | $>./union zpadinton "paqefwtdjetyiytjneytjoeyjnejeyj" | cat -e 17 | zpadintoqefwjy$ 18 | $>./union ddf6vewg64f gtwthgdwthdwfteewhrtag6h4ffdhsd | cat -e 19 | df6vewg4thras$ 20 | $>./union "rien" "cette phrase ne cache rien" | cat -e 21 | rienct phas$ 22 | $>./union | cat -e 23 | $ 24 | $> 25 | $>./union "rien" | cat -e 26 | $ 27 | $> 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exam_Rank_02 2 | ## 레포 설명 3 | - ft_printf로 통과하였습니다. ft_printf폴더 안에 ft_printf.c 파일을 참고해주세요 4 | - gnl은 테스트 쉘 파일이 주이지는데 그 파일을 통과하였습니다. 5 | 6 | ## 준비물 7 | * A4 8 | * 펜 9 | 10 | ## 시험시작하기 11 | * 티켓 만들기 12 | ~~~ 13 | kinit (인트라 id) 14 | ~~~ 15 | * examshell 접속하기 16 | ~~~ 17 | examshell 18 | ~~~ 19 | 20 | ## examshell 명령어 21 | * status : 상태 보기 22 | * grademe : 평가 받기 23 | * finish : 끝내기 24 | 25 | ## vim설정하기 26 | * 경로 위치 27 | ~~~ 28 | ~/.myvimrc 29 | ~~~ 30 | * 옵션 추가 31 | ~~~ 32 | set nu // 라인 번호 33 | syntax on // 글자 색상 34 | ~~~ 35 | 36 | ## printf 합격 github 37 | * https://github.com/juanlamarao/42_exam_rank_02/tree/master/ft_printf 38 | * https://github.com/HappyTramp/exam_rank_02/tree/master/rendu/ft_printf 39 | * https://github.com/drisshaou/ft_printf_exam_rank_02/blob/master/ft_printf.c 40 | * https://github.com/MikelTolino/exam_rank_02/tree/master/ft_printf 41 | * https://github.com/solaldunckel/exam_rank_02/blob/master/1-ft_printf/ft_printf.c 42 | * https://github.com/taelee42/42exam_rank02/tree/master/ft_printf 43 | -------------------------------------------------------------------------------- /ft_printf/subject.en.txt: -------------------------------------------------------------------------------- 1 | Assignment name : ft_printf 2 | Expected files : ft_printf.c 3 | Allowed functions: malloc, free, write, va_start, va_arg, va_copy, va_end 4 | -------------------------------------------------------------------------------- 5 | 6 | Write a function named `ft_printf` that will mimic the real printf with the following constraints: 7 | 8 | - It will manage only the following conversions: s,d and x 9 | - It will manage the minimum field width. (we will never test with a field with of 0) 10 | - It will manage only the precison flag `.`. 11 | 12 | Your function must be declared as follows: 13 | 14 | int ft_printf(const char *, ... ); 15 | 16 | Before you start we advise you to read the `man 3 printf` and the `man va_arg`. 17 | To test your program compare your results with the true printf. 18 | 19 | Exemples of the function output: 20 | 21 | call: ft_printf("%10.2s\n", "toto"); 22 | out: to$ 23 | 24 | call: ft_printf("Magic %s is %5d", "number", 42); 25 | out:Magic number is 42% 26 | 27 | call: ft_printf("Hexadecimal for %d is %x\n", 42, 42); 28 | out:Hexadecimal for 42 is 2a$ 29 | -------------------------------------------------------------------------------- /get_next_line/get_next_line.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: seunkim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/05/27 13:13:35 by seunkim #+# #+# */ 9 | /* Updated: 2020/05/27 16:23:16 by seunkim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef GET_NEXT_LINE_H 14 | # define GET_NEXT_LINE_H 15 | 16 | # include 17 | # include 18 | # include 19 | 20 | int get_next_line(char **line); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /inter/inter.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* inter.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: seunkim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/05/25 16:42:31 by seunkim #+# #+# */ 9 | /* Updated: 2020/05/25 17:13:30 by seunkim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | int i; 18 | int j; 19 | int temp; 20 | 21 | if (argc != 3) 22 | return (0); 23 | i = 0; 24 | while (argv[1][i]) 25 | { 26 | j = 0; 27 | while (argv[2][j]) 28 | { 29 | if (argv[1][i] == argv[2][j]) 30 | { 31 | temp = i; 32 | while (argv[1][--temp] && temp >= 0) 33 | { 34 | if (argv[1][temp] == argv[1][i]) 35 | break; 36 | } 37 | if (temp < 0) 38 | write(1, &argv[1][i], 1); 39 | break; 40 | } 41 | j++; 42 | } 43 | i++; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /get_next_line/subject.en.txt: -------------------------------------------------------------------------------- 1 | Assignment name : get_next_line 2 | Expected files : get_next_line.c get_next_line.h 3 | Allowed functions: read, free, malloc 4 | -------------------------------------------------------------------------------- 5 | 6 | Write a function will store, in the parameter "line", a line that has been read from the file descriptor 0. 7 | 8 | Your function must be prototyped as follows: int get_next_line(char **line); 9 | 10 | Your function should be memory leak free. 11 | 12 | What we call a "line that has been read" is a succession of 0 to n characters that end with '\n' (ascii code 0x0a) or with End Of File (EOF). 13 | 14 | The string stored in the parameter "line" should not contained any '\n'. 15 | 16 | The parameter is the address of a pointer to a character that will be used to store the line read. 17 | 18 | The return value can be 1, 0 or -1 depending on whether a line has been read, when the reading has been completed (meaning read has returned 0), or if an error has happened respectively. 19 | 20 | When you've reached the End Of File, you must store the current buffer in "line". If the buffer is empty you must store an empty string in "line". 21 | 22 | When you've reached the End Of File, your function should keep 0 memory allocated with malloc except the last buffer that you should have stored in "line". 23 | 24 | What you've stored in "line" should be free-able. 25 | 26 | Calling your function get_next_line in a loop will therefore allow you to read the text available on a file descriptor one line at a time until the end of the text, no matter the size of either the text or one of its lines. 27 | 28 | Make sure that your function behaves well when it reads from a file, from the standard output, from a redirection etc. 29 | 30 | No call to another function will be done on the file descriptor between 2 calls of get_next_line. 31 | 32 | Finally we consider that get_next_line has an undefined behavior when reading from a binary file. 33 | 34 | You should use the test.sh to help you test your get_next_line. 35 | -------------------------------------------------------------------------------- /get_next_line/README.md: -------------------------------------------------------------------------------- 1 | # get_next_line 2 | ## 문제 3 | ### 허용 함수 4 | read, free, malloc 5 | 6 | ### 제출 파일 7 | get_next_line.c, get_next_line.h 8 | 9 | ### 문제 번역 10 | * file descriptor 0(표준 입력 - stdin)에서 한 줄을 읽어와서 "line"에 저장하는 함수를 만들어라 11 | * int get_next_line(char **line); 12 | * 이 함수는 메모리 누수가 없어야 한다. 13 | * "라인을 읽어왔다"의 의미는 개행('\n')으로 끝나거나 파일의 끝(EOF)으로 끝나는 0에서 n개의 문자들을 읽어 왔다는 이야기이다. 14 | * line 에 저장될 값은 '\n'은 포함 되지 않는다. 15 | * line은 읽어온 한 줄을 저장할 곳 포인터의 주소이다. 16 | * 한줄을 읽어왔으면 리턴 1, 파일의 마지막 줄을 읽었으면 리턴 0, 애러가 발생했으면 리턴 -1. 17 | * 파일에 끝에 도달했을 때 현재 버퍼에 있는 값들을 line에 저장하고 만약 버퍼가 비어 있다면 빈 문자열을 line에 저장해야 한다. 18 | * 파일에 끝네 도달했을 때 마지막 버퍼를 제외하고는 모든 메모리는 해제되어야 한다. 19 | * line도 해제 가능한 변수여야 한다. 20 | * get_next_line은 반복문에서 작동하고 한줄의 길이가 얼마든 간에 fd 안에 있는 텍스트가 끝날때까지 반복문을 돌면서 한줄씩 읽어 온다. 21 | * 우리가 만든 함수는 표준 출력, 파일에서도 잘 읽어와야 한다. 22 | 23 | ## 메모리 누수 체크하기! 24 | * main 함수 마지막에 무한 루프 넣기 25 | ~~~c 26 | while (1) 27 | { 28 | } 29 | ~~~ 30 | 31 | * 컴파일 하고 실행 32 | ~~~shell 33 | ./a.out 34 | ~~~ 35 | 36 | * 다른 터미널을 열고 ps 명령어 사용해서 pid 값 찾기 37 | ~~~shell 38 | $ps 39 | ~~~ 40 | ~~~ 41 | PID TTY TIME CMD 42 | 468 ttys004 0:00.04 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp stevenkim 43 | 470 ttys004 0:00.58 -zsh 44 | 812 ttys005 0:00.51 /bin/zsh -l 45 | 5351 ttys005 0:03.03 ./a.out 46 | ~~~ 47 | 48 | * pid 값 넣어서 테스트 49 | ~~~shell 50 | while 1; do leaks 5351; sleep 3; clear; done 51 | ~~~ 52 | 53 | ~~~ 54 | ~/Desktop/42/Exam_Rank_02/get_next_line 55 | Process: a.out [5351] 56 | Path: /Users/USER/Desktop/*/a.out 57 | Load Address: 0x10a757000 58 | Identifier: a.out 59 | Version: ??? 60 | Code Type: X86-64 61 | Parent Process: zsh [812] 62 | 63 | Date/Time: 2020-06-01 23:37:29.540 +0900 64 | Launch Time: 2020-06-01 23:35:03.883 +0900 65 | OS Version: Mac OS X 10.15.4 (19E266) 66 | Report Version: 7 67 | Analysis Tool: /usr/bin/leaks 68 | 69 | Physical footprint: 300K 70 | Physical footprint (peak): 300K 71 | ---- 72 | 73 | leaks Report Version: 4.0 74 | Process 5351: 154 nodes malloced for 12 KB 75 | Process 5351: 0 leaks for 0 total leaked bytes 76 | ~~~ 77 | 78 | 79 | ## 문제 풀이 순서 80 | 1. get_next_line.h 파일 만들기 81 | 2. 함수 만들기 82 | - ft_strlen 83 | - ft_strjoin 84 | - ft_strchr 85 | - ft_strudup 86 | 3. 입력한 데이터를 static 변수에 저장되었는지 확인하기 87 | 4. main 함수를 만들어서 제대로 함수가 동작하는지 확인. 88 | -------------------------------------------------------------------------------- /ft_printf/README.md: -------------------------------------------------------------------------------- 1 | # ft_printf 2 | ## 문제 3 | ### 허용 함수 4 | malloc, free, write, va_start, va_arg, va_copy, va_end 5 | 6 | ### 문제 번역 7 | * %s(문자열), %d(10진수), %x(16진수) 8 | * width만 구현 9 | 10 | ## 처리 해야될 구간 11 | * %s 12 | ~~~c 13 | printf("10.0s |%10.0s\n", "Hello"); 14 | printf("10.s |%10.s\n", "Hello"); 15 | printf("10s |%10s\n", "Hello"); 16 | printf("10.4s |%10.4s\n", "HEllo"); 17 | printf("10.7s |%10.7s\n", "HEllo"); 18 | printf(".7s |%.7s\n", "HEllo"); 19 | printf(".3s |%.3s\n", "HEllo"); 20 | ~~~ 21 | 22 | ~~~ 23 | 10.0s | 24 | 10.s | 25 | 10s | Hello 26 | 10.4s | HEll 27 | 10.7s | HEllo 28 | .7s |HEllo$ 29 | .3s |HEl$ 30 | ~~~ 31 | 32 | * d 33 | ~~~c 34 | printf("d |%d\n", 1234); 35 | printf("3d |%3d\n", 1234); 36 | printf("7d |%7d\n", 1234); 37 | printf(".d |%.d\n", 1234); 38 | printf(".3d |%.3d\n", 1234); 39 | printf(".6d |%.6d\n", 1234); 40 | printf(".6d |%.6d\n", -1234); 41 | printf("3.3d |%3.3d\n", 1234); 42 | printf("3.3d |%3.3d\n", -1234); 43 | printf("6.3d |%6.3d\n", 1234); 44 | printf("6.3d |%6.3d\n", -1234); 45 | printf("3.7d |%3.7d\n", 1234); 46 | printf("3.7d |%3.7d\n", -1234); 47 | printf("9.7d |%9.7d\n", 1234); 48 | printf("9.7d |%9.7d\n", -1234); 49 | ~~~ 50 | 51 | ~~~ 52 | d |1234 53 | 3d |1234 54 | 7d | 1234 55 | .d |1234 56 | .3d |1234 57 | .6d |001234 58 | .6d |-001234 59 | 3.3d |1234 60 | 3.3d |-1234 61 | 6.3d | 1234 62 | 6.3d | -1234 63 | 3.7d |0001234 64 | 3.7d |-0001234 65 | 9.7d | 0001234 66 | 9.7d | -0001234 67 | ~~~ 68 | 69 | ### 출력된 값 파일에 저장하기 70 | ~~~shell 71 | ./a.out >> result.txt 72 | ~~~ 73 | 74 | # 시험 대비 75 | ## 구조체 76 | ~~~c 77 | typedef struct s_struct 78 | { 79 | char *format; 80 | 81 | char conversion; 82 | 83 | int nprinted; 84 | 85 | int width; 86 | int dot; 87 | int precision; 88 | } t_struct; 89 | ~~~ 90 | ## 만들어야 할 기본 함수 91 | * ft_strlen - 문자열 길이 92 | * ft_numlen - 10진수 길이 93 | * ft_hexlen - 16진수 길이 94 | * ft_putnstr - 문자열 n만큼 출력 95 | * ft_putnbr - 10진수 출력 96 | * ft_puthex - 16진수 출력 97 | * ft_isdigit - 숫자인지 확인 98 | * ft_isprint - 출력가능한 문자인지 확인 99 | * ft_strchr - 문자열 중에서 문자를 찾으면 그 위치 리턴 없으면 널 리턴 100 | * ft_strndup - n 만큼 문자열 할당 101 | 102 | ## 만들어야 할 커스텀 함수 103 | ### int ft_printf(const char *s, ...) 104 | * 메인 함수 105 | * va_list, va_start, va_end 사용 106 | 107 | ### int checkformat(const char *s, va_list ap) 108 | * 문자열 s를 while문으로 돌면서 '%'를 찾으면 처리해 주는 함수 109 | 110 | ### char *findspecifier(const char *s) 111 | * '%'를 찾았을때 그 뒤에 있는 서식자(s, d, x)까지를 찾아주는 함수 112 | 113 | ### void init(t_struct *f, char *format, char conversion) 114 | * 구조체 초기화 해주는 함수 115 | 116 | ### void handlewidthandflag(t_struct *f, va_list ap) 117 | * width, dot, flag 저장하는 함수 118 | 119 | ### void printstring(t_struct *f, va_list ap) 120 | * 문자열 출력 121 | 122 | ### void pringnumber(t_struch *f, va_list ap) 123 | * 10진수 16진수 124 | 125 | -------------------------------------------------------------------------------- /get_next_line/get_next_line.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: seunkim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/06/02 12:18:27 by seunkim #+# #+# */ 9 | /* Updated: 2020/06/02 13:02:41 by seunkim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | char *ft_strndup(char *s, int n) 18 | { 19 | int i; 20 | char *ptr; 21 | 22 | i = 0; 23 | if (!(ptr = (char *)malloc(sizeof(char) * (n + 1)))) 24 | return (NULL); 25 | while (s[i] && i < n) 26 | { 27 | ptr[i] = s[i]; 28 | i++; 29 | } 30 | ptr[i] = '\0'; 31 | return (ptr); 32 | } 33 | 34 | int ft_strlen(char *s) 35 | { 36 | int i; 37 | 38 | i = 0; 39 | while (s[i]) 40 | i++; 41 | return (i); 42 | } 43 | 44 | char *ft_strjoin(char *s1, char *s2) 45 | { 46 | int i; 47 | int s1_len; 48 | int s2_len; 49 | char *ptr; 50 | 51 | i = 0; 52 | s1_len = ft_strlen(s1); 53 | s2_len = ft_strlen(s2); 54 | if (!(ptr = (char *)malloc(sizeof(char) * (s1_len + s2_len + 1)))) 55 | return (NULL); 56 | while (i < s1_len) 57 | { 58 | ptr[i] = s1[i]; 59 | i++; 60 | } 61 | while (i - s1_len < s2_len) 62 | { 63 | ptr[i] = s2[i - s1_len]; 64 | i++; 65 | } 66 | ptr[i] = '\0'; 67 | return (ptr); 68 | } 69 | 70 | char *ft_strchr(char *s, int c) 71 | { 72 | int i; 73 | 74 | i = 0; 75 | while (s[i]) 76 | { 77 | if (s[i] == (char)c) 78 | return (s + i); 79 | i++; 80 | } 81 | if ((char)c == 0) 82 | return (s + i); 83 | else 84 | return (NULL); 85 | } 86 | 87 | int get_next_line(char **line) 88 | { 89 | static char *data; 90 | char *buff; 91 | ssize_t bytes; 92 | char *tmp; 93 | char *n_ptr; 94 | 95 | if (!(buff = (char*)malloc(sizeof(char) * 2))) 96 | return (-1); 97 | if (!data) 98 | { 99 | data = ft_strndup("", 0); 100 | while ((bytes = read(0, buff, 1) > 0)) 101 | { 102 | buff[bytes] = '\0'; 103 | tmp = data; 104 | data = ft_strjoin(data, buff); 105 | free(tmp); 106 | } 107 | } 108 | free(buff); 109 | n_ptr = ft_strchr(data, '\n'); 110 | if (n_ptr) 111 | { 112 | *line = ft_strndup(data, n_ptr - data); 113 | data += n_ptr - data + 1; 114 | return (1); 115 | } 116 | else 117 | { 118 | *line = ft_strndup(data, ft_strchr(data, '\0') - data); 119 | return (0); 120 | } 121 | } 122 | 123 | int main(void) 124 | { 125 | char *line; 126 | int ret; 127 | 128 | line = NULL; 129 | while ((ret = get_next_line(&line)) > 0) 130 | { 131 | printf("%d %s\n", ret, line); 132 | free(line); 133 | line = NULL; 134 | } 135 | printf("%d %s\n", ret, line); 136 | free(line); 137 | while (1) 138 | { 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /get_next_line/old_gnl/get_next_line.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: seunkim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/06/01 19:37:44 by seunkim #+# #+# */ 9 | /* Updated: 2020/06/01 19:37:45 by seunkim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | // #include "get_next_line.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | char *ft_strjoin(char const *s1, char const *s2) 21 | { 22 | char *ptr; 23 | int s1_len; 24 | int s2_len; 25 | int i; 26 | 27 | s1_len = strlen(s1); 28 | s2_len = strlen(s2); 29 | if (!(ptr = (char*)malloc(sizeof(char) * (s1_len + s2_len + 1)))) 30 | return (NULL); 31 | i = 0; 32 | while (s1[i] && i < s1_len) 33 | { 34 | ptr[i] = s1[i]; 35 | i++; 36 | } 37 | while (s2[i - s1_len] && i - s1_len < s2_len) 38 | { 39 | ptr[i] = s2[i - s1_len]; 40 | i++; 41 | } 42 | ptr[i] = '\0'; 43 | return (ptr); 44 | } 45 | 46 | char *ft_strndup(char *s, int n) 47 | { 48 | int i; 49 | char *str; 50 | 51 | if (!(str = (char*)malloc(sizeof(char) * (n + 1)))) 52 | return (NULL); 53 | i = 0; 54 | while (i < n) 55 | { 56 | str[i] = s[i]; 57 | i++; 58 | } 59 | str[i] = '\0'; 60 | return (str); 61 | } 62 | 63 | int get_next_line(char **line) 64 | { 65 | static char *data; 66 | char *buff; 67 | char *tmp; 68 | ssize_t bytes; 69 | int fd; 70 | 71 | // 버퍼사이즈 1 72 | fd = open("text.txt", O_RDONLY); 73 | if (!(buff = (char*)malloc(sizeof(char) * 2))) 74 | return (-1); 75 | if (!data) 76 | { 77 | data = ft_strndup("", 0); 78 | while ((bytes = read(fd, buff, 1)) > 0) 79 | { 80 | buff[bytes] = '\0'; 81 | tmp = data; 82 | data = ft_strjoin(data, buff); 83 | free(tmp); 84 | } 85 | //printf("data = %s\n", data); 86 | } 87 | free(buff); 88 | if (strchr(data, '\n')) 89 | { 90 | *line = ft_strndup(data, strchr(data, '\n') - data); 91 | data = strchr(data, '\n') + 1; 92 | return (1); 93 | } 94 | else 95 | { 96 | *line = ft_strndup(data, strchr(data, '\0') - data); 97 | //free(data); 98 | return (0); 99 | } 100 | } 101 | 102 | int main(void) 103 | { 104 | char *line; 105 | int ret; 106 | 107 | line = NULL; 108 | while ((ret = get_next_line(&line)) > 0) 109 | { 110 | printf("%d : %s\n", ret, line); 111 | free(line); 112 | line = NULL; 113 | } 114 | printf("%d : %s\n", ret, line); 115 | free(line); 116 | } 117 | -------------------------------------------------------------------------------- /get_next_line/old_gnl/get_next_line_ort.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: seunkim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/05/27 12:54:27 by seunkim #+# #+# */ 9 | /* Updated: 2020/05/27 16:23:57 by seunkim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | // #include "get_next_line.h" 14 | 15 | size_t ft_strlen(const char *s) 16 | { 17 | size_t count; 18 | 19 | count = 0; 20 | while (s[count]) 21 | count++; 22 | return (count); 23 | } 24 | 25 | char *ft_strchr(char *s, int c) 26 | { 27 | size_t idx; 28 | 29 | idx = 0; 30 | while (s[idx]) 31 | { 32 | if (s[idx] == (char)c) 33 | return (s + idx); 34 | idx++; 35 | } 36 | if (!(char)c) 37 | return (s + idx); 38 | else 39 | return (NULL); 40 | } 41 | 42 | char *ft_strjoin(char const *s1, char const *s2) 43 | { 44 | char *ptr; 45 | size_t s1_len; 46 | size_t s2_len; 47 | size_t idx; 48 | 49 | s1_len = ft_strlen(s1); 50 | s2_len = ft_strlen(s2); 51 | if (!(ptr = (char*)malloc(sizeof(char) * (s1_len + s2_len + 1)))) 52 | return (NULL); 53 | idx = 0; 54 | while (s1[idx] && idx < s1_len) 55 | { 56 | ptr[idx] = s1[idx]; 57 | idx++; 58 | } 59 | while (s2[idx - s1_len] && idx - s1_len < s2_len) 60 | { 61 | ptr[idx] = s2[idx - ft_strlen(s1)]; 62 | idx++; 63 | } 64 | ptr[idx] = '\0'; 65 | return (ptr); 66 | } 67 | 68 | char *ft_strndup(char const *s, int n) 69 | { 70 | int idx; 71 | char *ptr; 72 | 73 | idx = 0; 74 | if (!(ptr = (char*)malloc(sizeof(char) * (n + 1)))) 75 | return (NULL); 76 | while (idx < n) 77 | { 78 | ptr[idx] = s[idx]; 79 | idx++; 80 | } 81 | ptr[idx] = '\0'; 82 | return (ptr); 83 | } 84 | 85 | int check_error(char **buff, int fd) 86 | { 87 | if (!(*buff = (char*)malloc(sizeof(char) * (128 + 1)))) 88 | return (0); 89 | if (fd <= -1 || fd >= 6) 90 | return (0); 91 | return (1); 92 | } 93 | 94 | int getlinestr(char **line, char **data, char **first_data) 95 | { 96 | if (ft_strchr(*data, '\n')) 97 | { 98 | *line = ft_strndup(*data, ft_strchr(*data, '\n') - *data); 99 | *data = ft_strchr(*data, '\n') + 1; 100 | return (1); 101 | } 102 | else 103 | { 104 | *line = ft_strndup(*data, ft_strchr(*data, '\0') - *data); 105 | free(*first_data); 106 | *data = NULL; 107 | return (0); 108 | } 109 | } 110 | 111 | int get_next_line(char **line) 112 | { 113 | int fd; 114 | char *buff; 115 | static char *data[8192]; 116 | char *tmp; 117 | ssize_t bytes; 118 | 119 | fd = 0; 120 | if (line == NULL) 121 | return (-1); 122 | if (!(check_error(&buff, fd))) 123 | return (-1); 124 | if (!data[fd]) 125 | { 126 | data[fd] = ft_strndup("", 0); 127 | while ((bytes = read(fd, buff, 128)) > 0) 128 | { 129 | buff[bytes] = '\0'; 130 | tmp = data[fd]; 131 | data[fd] = ft_strjoin(data[fd], buff); 132 | free(tmp); 133 | } 134 | data[4096 + fd] = data[fd]; 135 | } 136 | free(buff); 137 | return (getlinestr(&*line, &data[fd], &data[4096 + fd])); 138 | } 139 | -------------------------------------------------------------------------------- /ft_printf/ft_printf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | // 9. 진수 숫자 출력 함수 8 | void ft_putnbr_base(long long num, int base) 9 | { 10 | char *dec = "0123456789"; 11 | char *hex = "0123456789abcdef"; 12 | 13 | if (num < 0) 14 | num = -num; 15 | if (num >= base) 16 | { 17 | ft_putnbr_base(num / base, base); 18 | ft_putnbr_base(num % base, base); 19 | } 20 | else 21 | { 22 | if (base == 10) 23 | write(1, &dec[num], 1); 24 | else if (base == 16) 25 | write(1, &hex[num], 1); 26 | } 27 | } 28 | 29 | // 8. 숫자 길이 함수 30 | int ft_numlen(int num) 31 | { 32 | int i; 33 | 34 | i = 1; 35 | while (num /= 10) 36 | i++; 37 | return (i); 38 | } 39 | 40 | int ft_hexlen(unsigned int num) 41 | { 42 | int i; 43 | 44 | i = 1; 45 | while (num /= 16) 46 | i++; 47 | return (i); 48 | } 49 | 50 | // 7. n 만큼 문자열 출력 함수 51 | void ft_putnstr(char *s, int n) 52 | { 53 | int i; 54 | 55 | i = 0; 56 | while (s[i] && i < n) 57 | { 58 | write(1, &s[i], 1); 59 | i++; 60 | } 61 | } 62 | 63 | // 6. 문자열 길이 함수 64 | int ft_strlen(char *s) 65 | { 66 | int i; 67 | 68 | i = 0; 69 | while (s[i]) 70 | i++; 71 | return (i); 72 | } 73 | 74 | // 5. width dot precision 처리하고 출력하는 함수 75 | int printwithflags(char *f, char conversion, va_list ap) 76 | { 77 | int width; 78 | int dot; 79 | int precision; 80 | int nprinted; 81 | int i; 82 | 83 | width = 0; 84 | dot = 0; 85 | precision = 0; 86 | nprinted = 0; 87 | i = 0; 88 | while (f[i]) 89 | { 90 | if ((f[i] >= '0' && f[i] <= '9') && !dot) 91 | width = (width * 10) + (f[i] - 48); 92 | else if (f[i] == '.') 93 | dot = 1; 94 | else if ((f[i] >= '0' && f[i] <= '9') && dot) 95 | precision = (precision * 10) + (f[i] - 48); 96 | i++; 97 | } 98 | //printf("%d %d %d\n", width, dot, precision); 99 | 100 | char *str; 101 | int num; 102 | unsigned int unum; 103 | int len; 104 | 105 | num = 0; 106 | unum = 0; 107 | len = 0; 108 | if (conversion == 's') 109 | { 110 | if (!(str = va_arg(ap, char *))) 111 | str = "(null)"; 112 | len = ft_strlen(str); 113 | if (dot) 114 | { 115 | if (len < precision) 116 | precision = len; 117 | } 118 | else // . 이 없으면 pre = 0이기 떄문에 119 | precision = len; 120 | i = 0; // 공백 출력 121 | while (i < width - precision) 122 | { 123 | write(1, " ", 1); 124 | nprinted++; 125 | i++; 126 | } 127 | nprinted += precision; 128 | ft_putnstr(str, precision); 129 | } 130 | else if (conversion == 'd' || conversion == 'x') 131 | { 132 | if (conversion == 'd') 133 | { 134 | num = va_arg(ap, int); 135 | len = ft_numlen(num); 136 | } 137 | else if (conversion == 'x') 138 | { 139 | unum = va_arg(ap, unsigned int); 140 | len = ft_hexlen(unum); 141 | } 142 | if (num == 0 && unum == 0 && dot && precision == 0) // 예외처리 143 | { 144 | i = 0; 145 | while (i < width) 146 | { 147 | write(1, " ", 1); 148 | nprinted++; 149 | i++; 150 | } 151 | return (nprinted); 152 | } 153 | if (precision < len) 154 | precision = len; 155 | if (num < 0) // 공백 처리 156 | precision++; 157 | i = 0; 158 | while (i < width - precision) 159 | { 160 | write(1, " ", 1); 161 | nprinted++; 162 | i++; 163 | } 164 | if (num < 0) // '-' 출력 165 | { 166 | write(1, "-", 1); 167 | len++; 168 | } 169 | i = 0; // 0 처리 170 | while (i < precision - len) 171 | { 172 | write(1, "0", 1); 173 | i++; 174 | } 175 | nprinted += precision; 176 | if (conversion == 'd') 177 | ft_putnbr_base(num, 10); 178 | else if (conversion == 'x') 179 | ft_putnbr_base(unum, 16); 180 | } 181 | free(f); 182 | return (nprinted); 183 | } 184 | 185 | // 4. n 길이 만큼 새로운 문자열 할당 함수 186 | char *ft_strndup(char *s, int n) 187 | { 188 | int i; 189 | char *ptr; 190 | 191 | if (!(ptr = (char *)malloc(sizeof(char *) * (n + 1)))) 192 | return (NULL); 193 | i = 0; 194 | while (s[i] && i < n) 195 | { 196 | ptr[i] = s[i]; 197 | i++; 198 | } 199 | ptr[i] = '\0'; 200 | return (ptr); 201 | } 202 | 203 | // 3. 서식자의 위치를 찾아주는 함수 204 | char *findsdx(char *s) 205 | { 206 | int i; 207 | 208 | i = 0; 209 | while (s[i] && ((s[i] >= '0' && s[i] <= '9') || s[i] == '.')) 210 | i++; 211 | if (s[i] >= 32 && s[i] <= 126) 212 | { 213 | //printf("s[i] = %c\n", s[i]); 214 | if (s[i] == 's' || s[i] == 'd' || s[i] == 'x') 215 | return (s + i); 216 | else 217 | return (NULL); 218 | } 219 | return (NULL); 220 | } 221 | 222 | // 2. %를 찾아서 처리해주는 함수 223 | int checkformat(va_list ap, char *s) 224 | { 225 | int i; 226 | char *conversion; 227 | int ret; 228 | char *format; 229 | 230 | ret = 0; 231 | i = 0; 232 | while (s[i]) 233 | { 234 | if (s[i] == '%') 235 | { 236 | conversion = findsdx(s + i + 1); 237 | //printf("con = %c\n", *conversion); 238 | if (conversion) 239 | { // fstrndup s + i 하는 것이 포인트! 240 | format = ft_strndup(s + i, (conversion + 1) - (s + i)); 241 | //printf("format = %s\n", format); 242 | ret += printwithflags(format, *conversion, ap); 243 | i += ((conversion) - (s + i)); 244 | } 245 | else // sdx가 없을 때 한 칸 앞으로 246 | i++; 247 | } 248 | else // % 없는 문자는 그냥 출력 249 | { 250 | write(1, &s[i], 1); 251 | ret++; 252 | } 253 | i++; 254 | } 255 | return (ret); 256 | } 257 | 258 | // 1. 프로토 타입 함수 259 | int ft_printf(const char *s, ...) 260 | { 261 | int ret; 262 | va_list ap; 263 | 264 | if (!s) 265 | return (-1); 266 | va_start(ap, s); 267 | // 상수 타입을 일반 타입으로 변환 중요!! 268 | ret = checkformat(ap, (char *)s); 269 | va_end(ap); 270 | return (ret); 271 | } 272 | 273 | -------------------------------------------------------------------------------- /ft_printf/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | ft_printf(char const *format, ...); 6 | 7 | #ifndef REAL 8 | # define F r += ft_printf 9 | #else 10 | # define F r += printf 11 | #endif 12 | 13 | int 14 | main(void) 15 | { 16 | int r; 17 | 18 | r = 0; 19 | F("Simple test\n"); 20 | F(""); 21 | F("--Format---"); 22 | F("\n"); 23 | F("%d", 0); 24 | F("%d", 42); 25 | F("%d", 1); 26 | F("%d", 5454); 27 | F("%d", (int)2147483647); 28 | F("%d", (int)2147483648); 29 | F("%d", (int)-2147483648); 30 | F("%d", (int)-2147483649); 31 | F("\n"); 32 | F("%x", 0); 33 | F("%x", 42); 34 | F("%x", 1); 35 | F("%x", 5454); 36 | F("%x", (int)2147483647); 37 | F("%x", (int)2147483648); 38 | F("%x", (int)-2147483648); 39 | F("%x", (int)-2147483649); 40 | F("%s", ""); 41 | F("%s", "toto"); 42 | F("%s", "wiurwuyrhwrywuier"); 43 | F("%s", NULL); 44 | F("-%s-%s-%s-%s-\n", "", "toto", "wiurwuyrhwrywuier", NULL); 45 | F("\n--Mixed---\n"); 46 | F("%d%x%d%x%d%x%d%x\n", 0, 0, 42, 42, 2147483647, 2147483647, (int)-2147483648, (int)-2147483648); 47 | F("-%d-%x-%d-%x-%d-%x-%d-%x-\n", 0, 0, 42, 42, 2147483647, 2147483647, (int)-2147483648, (int)-2147483648); 48 | F("\n"); 49 | F("%s%s%s%s\n", "", "toto", "wiurwuyrhwrywuier", NULL); 50 | F("-%s-%s-%s-%s-\n", "", "toto", "wiurwuyrhwrywuier", NULL); 51 | F("--1 Flag--\n"); 52 | F("d0w %0d %0d %0d %0d %0d %0d %0d %0d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 53 | F("d4w %4d %4d %4d %4d %4d %4d %4d %4d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 54 | F("d10w %10d %10d %10d %10d %10d %10d %10d %10d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 55 | F("d0p %.0d %.0d %.0d %.0d %.0d %.0d %.0d %.0d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 56 | F("d4p %.4d %.4d %.4d %.4d %.4d %.4d %.4d %.4d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 57 | F("d10p %.10d %.10d %.10d %.10d %.10d %.10d %.10d %.10d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 58 | F("x0w %0x %0x %0x %0x %0x %0x %0x %0x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 59 | F("x4w %4x %4x %4x %4x %4x %4x %4x %4x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 60 | F("x10w %10x %10x %10x %10x %10x %10x %10x %10x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 61 | F("x0p %.0x %.0x %.0x %.0x %.0x %.0x %.0x %.0x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 62 | F("x4p %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 63 | F("x10p %.10x %.10x %.10x %.10x %.10x %.10x %.10x %.10x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 64 | F("s0p ~%.0s` ~%.0s` ~%.0s` ~%.0s` ~%.0s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 65 | F("s4w ~%4s` ~%4s` ~%4s` ~%4s` ~%4s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 66 | F("s4p ~%.4s` ~%.4s` ~%.4s` ~%.4s` ~%.4s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 67 | F("s10w ~%10s` ~%10s` ~%10s` ~%10s` ~%10s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 68 | F("s10p ~%.10s` ~%.10s` ~%.10s` ~%.10s` ~%.10s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 69 | F("--2 Flags--\n"); 70 | F("d0w0p %0.0d %0.0d %0.0d %0.0d %0.0d %0.0d %0.0d %0.0d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 71 | F("x0w0p %0.0x %0.0x %0.0x %0.0x %0.0x %0.0x %0.0x %0.0x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 72 | F("--Precision--\n"); 73 | F("d0w4p %0.4d %0.4d %0.4d %0.4d %0.4d %0.4d %0.4d %0.4d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 74 | F("d0w10p %0.10d %0.10d %0.10d %0.10d %0.10d %0.10d %0.10d %0.10d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 75 | F("x0w4p %0.4x %0.4x %0.4x %0.4x %0.4x %0.4x %0.4x %0.4x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 76 | F("x0w10p %0.10x %0.10x %0.10x %0.10x %0.10x %0.10x %0.10x %0.10x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 77 | F("--Width--\n"); 78 | F("d4w0p %4.0d %4.0d %4.0d %4.0d %4.0d %4.0d %4.0d %4.0d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 79 | F("d10w0p %10.0d %10.0d %10.0d %10.0d %10.0d %10.0d %10.0d %10.0d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 80 | F("x4w0p %4.0x %4.0x %4.0x %4.0x %4.0x %4.0x %4.0x %4.0x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 81 | F("x10w0p %10.0x %10.0x %10.0x %10.0x %10.0x %10.0x %10.0x %10.0x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 82 | F("s4w0p ~%4.s` ~%4.s` ~%4.s` ~%4.s` ~%4.s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 83 | F("s10w0p ~%10.0s` ~%10.0s` ~%10.0s` ~%10.0s` ~%10.0s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 84 | F("--Width and Precision--\n"); 85 | F("d10w4p %10.4d %10.4d %10.4d %10.4d %10.4d %10.4d %10.4d %10.4d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 86 | F("d10w10p %10.10d %10.10d %10.10d %10.10d %10.10d %10.10d %10.10d %10.10d\n", 0, 1, 42, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 87 | F("d4w4p %4.4d %4.4d %4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 88 | F("d4w10p %4.10d %4.10d %4.10d %4.10d %4.10d %4.10d %4.10d %4.10d\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 89 | F("x10w4p %10.4x %10.4x %10.4x %10.4x %10.4x %10.4x %10.4x %10.4x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 90 | F("x10w10p %10.10x %10.10x %10.10x %10.10x %10.10x %10.10x %10.10x %10.10x\n", 0, 1, 42, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 91 | F("x4w4p %4.4x %4.4x %4.4x %4.4x %4.4x %4.4x %4.4x %4.4x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 92 | F("x4w10p %4.10x %4.10x %4.10x %4.10x %4.10x %4.10x %4.10x %4.10x\n", 0, 42, 1, 4554, 2147483647, (int)2147483648, (int)-2147483648, (int)-2147483649); 93 | F("s10w4p ~%10.4s` ~%10.4s` ~%10.4s` ~%10.4s` ~%10.4s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 94 | F("s10w10p ~%10.10s` ~%10.10s` ~%10.10s` ~%10.10s` ~%10.10s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 95 | F("s4w4p ~%4.4s` ~%4.4s` ~%4.4s` ~%4.4s` ~%4.4s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 96 | F("s4w10p ~%10.10s` ~%10.10s` ~%10.10s` ~%10.10s` ~%10.10s`\n", "", "toto", "0123456789", "tjehurthteutuiehteute", NULL); 97 | printf("written: %d\n", r); 98 | } -------------------------------------------------------------------------------- /ft_printf/old_printf/ft_printf.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_printf.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: seunkim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/05/27 17:13:35 by seunkim #+# #+# */ 9 | /* Updated: 2020/05/27 17:18:58 by seunkim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | typedef struct s_struct 21 | { 22 | char *format; 23 | 24 | char conversion; 25 | 26 | int nprinted; 27 | 28 | int width; 29 | int dot; 30 | int precision; 31 | } t_struct; 32 | 33 | // 문자열 길이 34 | int ft_strlen(char *s) 35 | { 36 | int i; 37 | 38 | i = 0; 39 | while (s[i]) 40 | i++; 41 | return (i); 42 | } 43 | 44 | // 숫자 길이 45 | int ft_numlen(int num) 46 | { 47 | int i; 48 | 49 | i = 1; 50 | while (num /= 10) 51 | i++; 52 | return (i); 53 | } 54 | 55 | // 16진수 길이 56 | int ft_hexlen(unsigned int num) 57 | { 58 | int i; 59 | 60 | i = 1; 61 | while (num /= 16) 62 | i++; 63 | return (i); 64 | } 65 | 66 | // 문자열 출력 67 | void ft_putnstr(char *s, int n) 68 | { 69 | int i; 70 | 71 | i = 0; 72 | while (s[i] && i < n) 73 | { 74 | write(1, &s[i], 1); 75 | i++; 76 | } 77 | } 78 | 79 | // 10진수 출력 80 | void ft_putnbr(long long num) 81 | { 82 | int i; 83 | 84 | i = 0; 85 | if (num < 0) 86 | num = -num; 87 | if (num >= 10) 88 | { 89 | ft_putnbr(num / 10); 90 | ft_putnbr(num % 10); 91 | } 92 | else 93 | { 94 | num += 48; 95 | write(1, &num, 1); 96 | } 97 | } 98 | 99 | // 16진수 출력 100 | void ft_puthex(long long num) 101 | { 102 | char *hex; 103 | 104 | hex = "0123456789abcdef"; 105 | if (num < 0) 106 | num = -num; 107 | if (num >= 16) 108 | { 109 | ft_puthex(num / 16); 110 | ft_puthex(num % 16); 111 | } 112 | else 113 | write(1, &hex[num], 1); 114 | } 115 | 116 | // n만큼 까지 문자열 할당 함수 117 | char *ft_strndup(char const *s, int n) 118 | { 119 | int i; 120 | char *ptr; 121 | 122 | i = 0; 123 | if (!(ptr = (char*)malloc(sizeof(char) * (n + 1)))) 124 | return (NULL); 125 | while (i < n) 126 | { 127 | ptr[i] = s[i]; 128 | i++; 129 | } 130 | ptr[i] = '\0'; 131 | return (ptr); 132 | } 133 | 134 | // 서식자를 찾아서 리턴하는 함수 135 | char *findspecifier(const char *s) 136 | { 137 | int i; 138 | char *conversion; 139 | 140 | i = 0; 141 | // 숫자랑 '.' 만 포함. 142 | while (s[i] && (isdigit(s[i]) || s[i] == '.')) 143 | i++; 144 | if (isprint(s[i])) 145 | { 146 | conversion = strchr("sdx", s[i]); 147 | if (conversion) 148 | return ((char*)s + i); 149 | else 150 | return (NULL); 151 | } 152 | return (NULL); 153 | } 154 | 155 | // 구조체 초기화 156 | void init(t_struct *f, char *format, char conversion) 157 | { 158 | f->format = format; 159 | f->conversion = conversion; 160 | f->nprinted = 0; 161 | f->width = 0; 162 | f->dot = 0; 163 | f->precision = 0; 164 | } 165 | 166 | void printstring(t_struct *f, va_list ap) 167 | { 168 | char *str; 169 | int len; 170 | int i; 171 | // 문자열에 null 일떄 처리 172 | if (!(str = va_arg(ap, char *))) 173 | str = "(null)"; 174 | len = ft_strlen(str); 175 | // presicion 처리 176 | if (f->dot) 177 | { 178 | if (len < f->precision) 179 | f->precision = len; 180 | } 181 | // presicion이 없을 때 182 | else 183 | f->precision = len; 184 | i = 0; 185 | // 공백 출력 186 | if (f->width > f->precision) 187 | { 188 | while (i < (f->width - f->precision)) 189 | { 190 | write(1, " ", 1); 191 | f->nprinted += 1; 192 | i++; 193 | } 194 | } 195 | ft_putnstr(str, f->precision); 196 | f->nprinted += f->precision; 197 | } 198 | 199 | void printnumber(t_struct *f, va_list ap) 200 | { 201 | int num; 202 | unsigned int unum; 203 | int len; 204 | int i; 205 | num = 0; 206 | unum = 0; 207 | // 10진수 일때 208 | if (f->conversion == 'd') 209 | { 210 | num = va_arg(ap, int); 211 | len = ft_numlen(num); 212 | } 213 | // 16진수 일때 214 | else if (f->conversion == 'x') 215 | { 216 | unum = va_arg(ap, unsigned int); 217 | len = ft_hexlen(unum); 218 | } 219 | // %.d, 0 / %4.0d, 0 처리 220 | if (((unum == 0 && num == 0) && f->dot && f->precision == 0)) 221 | { 222 | i = 0; 223 | while (i < f->width) 224 | { 225 | write(1, " ", 1); 226 | f->nprinted++; 227 | i++; 228 | } 229 | return ; 230 | } 231 | if (f->precision < len) 232 | f->precision = len; 233 | i = 0; 234 | if (num < 0) 235 | f->precision++; 236 | // 공백 237 | while (i < f->width - f->precision) 238 | { 239 | write(1, " ", 1); 240 | f->nprinted++; 241 | i++; 242 | } 243 | // 음수 '-' 처리 244 | if (num < 0) 245 | { 246 | write(1, "-", 1); 247 | len++; 248 | } 249 | // precision에 따라 0 출력 250 | i = 0; 251 | while (i < f->precision - len) 252 | { 253 | write(1, "0", 1); 254 | i++; 255 | } 256 | if (f->conversion == 'd') 257 | ft_putnbr(num); 258 | else if (f->conversion == 'x') 259 | ft_puthex(unum); 260 | f->nprinted += f->precision; 261 | } 262 | 263 | // width '.' presicion 처리하기 264 | void handlewidthandflag(t_struct *f, va_list ap) 265 | { 266 | int i; 267 | 268 | i = 0; 269 | while (f->format[i]) 270 | { 271 | // witdh 272 | if (isdigit(f->format[i]) && !(f->dot)) 273 | f->width = (f->width) * 10 + (f->format[i] - 48); 274 | // flag ',' 275 | else if (f->format[i] == '.' && !(f->dot)) 276 | f->dot = 1; 277 | // presicion 278 | else if (isdigit(f->format[i]) && (f->dot)) 279 | f->precision = (f->precision) * 10 + (f->format[i] - 48); 280 | i++; 281 | } 282 | // 문자열 283 | if (f->conversion == 's') 284 | printstring(f, ap); 285 | // 10진수, 16진수 286 | else if (f->conversion == 'd' || f->conversion == 'x') 287 | printnumber(f, ap); 288 | } 289 | 290 | // 서식자를 확인해서 처리해 주는 함수 291 | int checkformat(const char *s, va_list ap) 292 | { 293 | int i; 294 | int ret; 295 | t_struct *f; 296 | char *tmp; 297 | 298 | ret = 0; 299 | if (!(f = (t_struct*)malloc(sizeof(t_struct)))) 300 | return (0); 301 | i = 0; 302 | while (s[i]) 303 | { 304 | if (s[i] == '%') 305 | { 306 | // % 다음 부터 찾기 307 | tmp = findspecifier(s + i + 1); 308 | if (tmp) 309 | { 310 | init(f, ft_strndup(s + i, (tmp + 1) - (s + i)), *tmp); 311 | handlewidthandflag(f, ap); 312 | i = i + ((tmp) - (s + i)); 313 | ret += f->nprinted; 314 | } 315 | else 316 | i++; 317 | } 318 | // %가 아닐때는 기본 출력 기능만 함. 319 | else 320 | { 321 | ret += 1; 322 | write(1, &s[i], 1); 323 | } 324 | i++; 325 | } 326 | return (ret); 327 | } 328 | 329 | // 프로토타입 함수 330 | int ft_printf(const char *s, ...) 331 | { 332 | va_list ap; 333 | int ret; 334 | 335 | if (!s) 336 | return (0); 337 | va_start(ap, s); 338 | ret = checkformat(s, ap); 339 | va_end(ap); 340 | return (ret); 341 | } 342 | --------------------------------------------------------------------------------