[Libft] Part 1, 2

최별 Choi Byeol·2022년 5월 11일
1

42Seoul

목록 보기
2/6

나만의 C 라이브러리를 만들어 보는 과제

<Part 1>

1. ft_isalpha

#include "libft.h"

int ft_isalpha(int c)
{
    return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
}
  • 매개변수로 들어온 인자가 알파벳인지 확인하는 함수.
  • 인자가 알파벳이면 0이 아닌 수를 반환, 알파벳이 아니라면 0을 반환
  • 더 정확하게 얘기하면 “A-Z”는 1을 반환, 소문자 ‘a-z’는 2를 반환. 알파벳이 아니면 0을 반환
  • 출처: https://blockdmask.tistory.com/448

2. ft_isdigit

#include "libft.h"

int ft_isdigit(int c)
{
    if (c >= '0' && c <= '9')
			return (1);
    else
			return (0);
}
  • 매개변수로 들어온 인자가 숫자인지 확인하는 함수
  • 매개변수로 들어온 char 타입이 숫자로 변경 가능하면 0이 아닌 숫자(true), 아니면 0(false)를 반환
  • int 타입으로 받는 이유? char 타입이 아스키 코드 번호로 들어갈 수 있기 때문 → 따라서 아스키 코드표에서 48~57번에 매칭되는 문자 ‘0’, ‘1’, ... ,‘9’가 들어오면 True를 반환하는 형태
  • 출처: https://blockdmask.tistory.com/362

3. ft_isalnum

#include "libft.h"

int ft_isalnum(int c)
{
    return (ft_isdigit(c) || ft_isalpha(c));
}
  • 알파벳 또는 숫자인지 판단하는 함수
  • 알파벳 또는 숫자이면 0이 아닌 수를 반환, 아니면 0을 반환

4. ft_isascii

#include "libft.h"

int ft_isascii(int c)
{
    return (c >= 0 && c < 128);
}
  • 인수로 받은 문자가 ASCII 문자인지 확인하는 함수
  • 아스키 문자라면 0이 아닌 값을 반환하고 아스키 문자가 아니라면 0을 반환
  • 0~127의 값이면 아스키 문자

5. ft_isprint

#include "libft.h"

int ft_isprint(int c)
{
    return (c >= 32 && c <= 126);
}
  • 출력 가능한 문자인지 확인하는 함수
  • 출력할 수 있는 문자면 0이 아닌 값을 반환, 아니면 0을 반환
  • 32~126의 값이면 출력 가능

6. ft_strlen

#include "libft.h"

size_t  ft_strlen(const char *s)
{
    size_t  i;

		i = 0;
    while (s[i])
			i++;
    return (i);
}
  • const char* 타입의 문자열을 받아서 해당 문자열의 길이를 반환하는 함수
  • size_t는 C/C++에서 쓰는 데이터 타입으로, 해당 시스템에서 어떤 객체나 값이 포함할 수 있는 최대 크기의 데이터를 표현하는 타입으로 반드시 unsigned 형으로 나타낸다.
  • 보통은 “unsigned 정수” 타입으로 알고 있어도 된다. 보통 사용할 때는 int로 형변환을 해서 많이 사용
  • size_t의 대체품을 찾는다면 쓸 수 있는 가장 좋은 것은 int, 필요하다면 unsigned int

7. ft_memset

#include "libft.h"

void    *ft_memset(void *b, int c, size_t len)
{
    char    *str;
    size_t  i;

		str = (unsigned char *)b;
    i = 0;
    while (i < len)
    {
			str[i] = (unsigned char)c;
			i++;
    }
    return (b);
}
  • 메모리의 내용(값)을 원하는 크기만큼 특정 값으로 세팅할 수 있는 함수
  • memory + setting 메모리를 (특정 값으로) 세팅
  • 첫 번째 인자 void *b은 세팅하고자 하는 메모리의 시작 주소, 즉, 그 주소를 가리키고 있는 포인터가 위치하는 자리
  • 두 번째 인자 int c는 메모리에 세팅하고자 하는 값. int 타입으로 받지만 내부에서는 unsigned char로 변환되어서 저장. 즉 ‘a’와 같은 것을 넣어도 무방
  • 세 번째 인자 size_t len은 길이를 뜻함. 바이트 단위로써 메모리의 크기 한 조각 단위의 길이를 말함. 보통 “길이 * sizeof(데이터 타입)”의 형태로 작성
  • 반환값은 성공하면 첫 번째 인자로 들어간 b를 반환하고, 실패하면 NULL을 반환
  • 헤더 파일은 memory.h 또는 string.h 둘 중 하나를 사용해도 무방. 두 개 다 memset 함수가 정의
  • 출처: https://blockdmask.tistory.com/441

8. ft_bzero

#include "libft.h"

void    ft_bzero(void *s, size_t n)
{
    char    *str;
    size_t  i;

		str = s;
    i = 0;
    while (i < n)
    {
			str[i] = 0;
			i++;
    }
}
  • s의 메모리 공간을 n만큼 0으로 채우는 함수.

9. ft_memcpy

#include "libft.h"

void    *ft_memcpy(void *dst, const void *src, size_t n)
{
    size_t  i;

		i = 0;
    if (dst == src)
			return (dst);
    while (i < n)
    {
			((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
			i++;
    }
    return (dst);
}
  • memory + copy. 메모리의 값을 복사하는 기능을 하는 함수
  • memcpy(복사 받을 메모리, 복사할 메모리, 길이)
  • 매개변수
    • void *dst 복사 받을 메모리를 가리키는 포인터
    • const void *src 복사할 메모리를 가리키고 있는 포인터
    • size_t n 복사할 데이터(값)의 길이(바이트 단위)
  • src 메모리에 있는 값들을 n만큼 dst에 복사해서 붙여넣는 함수
  • 주의사항
    • strcpy 함수와 다르게 src의 \0을 검사하지 않는다.
    • 이미 dst와 src가 같다면 dst의 주소를 바로 반환
    • 길이를 계산할 때 char * 타입의 C언어 문자열 전체를 복사할 때는 맨 뒤에 문자열의 끝을 알리는 “\0”의 길이도 계산해서 넣어야 하기 때문에 +1의 길이만큼 해주어야 한다.
    • src 메모리 블록과 dst의 메모리 블록이 겹쳐져 있는 곳에서는 사용하지 못한다. 즉, 복사할 메모리양, 복사한 결과값을 붙여넣을 메모리가 겹쳐져 있다면 함수가 제대로 작동하지 않는다. 만약 동일한 메모리 공간에 덮어씌워야 한다면 memmove 함수를 사용
  • https://blockdmask.tistory.com/442

10. ft_memmove

#include "libft.h"

void    *ft_memmove(void *dst, const void *src, size_t len)
{
    size_t  i;
    int     pos;

		i = 0;
    if (src == NULL && dst == NULL)
			return (dst);
    if (dst < src)
    {
			while (i < len)
			{
				((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
				i++;
			}
    }
    else
    {
			while (i < len)
			{
				pos = len - 1 - i;
				((unsigned char *)dst)[pos] = ((unsigned char *)src)[pos];
				i++;
			}
    }
    return (dst);
}
  • memory + move. 메모리를 이동

  • 첫 번째 인자 void *dst 복사한 걸 붙여넣을 메모리를 가리키는 포인터 (목적지)

  • 두 번째 인자 void *src 복사할 메모리를 가리키는 포인터 (출발지)

  • 세 번째 인자 size_t len 복사할 바이트 길이

  • 첫 번째 인자인 dst를 반환

  • src가 가리키는 메모리로부터 len 바이트 사이즈만큼 dst가 가리키는 메모리에 옮긴다. memcpy는 어딘가를 거치지 않고 바로 그 위치에 복사해서 붙여넣는 함수고, memmove는 복사할 것을 버퍼에 복사하고, 해당 위치에 가서 버퍼에 복사된 것을 붙여 넣는 식으로 구현되어 있다.

  • 성능을 따지자면 memcpy가 버퍼를 거치지 않고 복사하기 때문에 좀 더 좋지만, 버퍼를 이용하는 memmove가 안정성이 더 뛰어나다.

  • 정리: memmove 함수도 메모리를 src에서 dst로 len 길이만큼 복사하는 함수이다. 중간에 버퍼를 이용해서 복사를 하므로 안정성이 memcpy보다 뛰어나다.

  • 출처: https://blockdmask.tistory.com/444

11. ft_strlcpy

#include "libft.h"

size_t  ft_strlcpy(char *dst, const char *src, size_t size)
{
	size_t  i;

	i = 0;
  if (size > 0)
	{
			while (src[i] && i < (size - 1))
			{
					dst[i] = src[i];
					i++;
			}
			dst[i] = 0;
  }
  while (src[i])
			i++;
  return (i);
}
  • 문자열 복사 함수. src에서 dst로 최대 size - 1만큼 복사하고 size가 0이 아닌 경우 결과를 NULL 종료
  • src의 ‘\0’ 값을 만나기 전 혹은 size - 1만큼 복사가 이루어졌을 때 복사를 중지
  • char *dst 복사가 진행될 목적지
  • const char *src 복사를 해야하는 값이 들어있는 포인터
  • size_t size 최대 size - 1만큼만 복사를 진행. (마지막에 ‘\0’값)
  • 복사하려 했던 문자열의 길이를 반환
  • 복사를 진행한 후 ‘\0’값을 넣어주기 때문에 strcpy, strncpy보다 안정성이 좋은 함수이다.

12. ft_strlcat

#include "libft.h"

size_t  ft_strlcat(char *dst, const char *src, size_t size)
{
    size_t  i;
    size_t  j;
    size_t  dst_len;
    size_t  src_len;

		src_len = ft_strlen(src);
    dst_len = ft_strlen(dst);
    j = dst_len;
    i = 0;
    if (dst_len < size - 1 && size > 0)
    {
				while (src[i] && dst_len + i < size - 1)
				{
						dst[j] = src[i];
						j++;
						i++;
				}
				dst[j] = 0;
	  }
    if (dst_len >= size)
				dst_len = size;
    return (dst_len + src_len);
}
  • 두 문자열을 붙이는 함수. 문자열 src를 dst의 끝에 추가한다.
  • dst의 맨 뒤에 src를 size만큼 붙인다. 만약 size가 dst의 길이 이하라면 문자열을 붙이는 과정이 사라지고, size가 더 크다면 size - 1만큼 src를 붙이고 마지막에 ‘\0’값을 넣어주고 리턴 값은 dst의 길이 + src의 길이이다.
  • size가 dst 길이보다 작을때 strlen + size가 반환되는 이유
    • ref_link
    • src와 dst를 합쳤을때 해당 문자열이 잘렸는지 아닌지를 strlen(res) 값 < strlcat(dst, src, ..)의 리턴값으로 체크할 수 있게 하기 위해.
  • 사용 예제: https://velog.io/@meong9090/42seoul-strlcat은-어떤-함수일까

13. ft_toupper

#include "libft.h"

int ft_toupper(int c)
{
    if (c >= 'a' && c <= 'z')
			c -= 32;
    return (c);
}
  • 소문자만 대문자로 변경해서 반환해주고 다른 모든 문자는 그대로 반환하는 함수

14. ft_tolower

#include "libft.h"

int ft_tolower(int c)
{
    if (c >= 'A' && c <= 'Z')
			c += 32;
    return (c);
}
  • 대문자만 소문자로 변경해서 반환해주고 다른 모든 문자는 그대로 반환하는 함수

15. ft_strchr

#include "libft.h"

char    *ft_strchr(const char *s, int c)
{
    while (*s)
    {
			if (*s == (char)c)
				return ((char *)s);
			++s;
    }
    if (*s == (char)c)
			return ((char *)s);
    return (0);
}
  • 문자열 내에 일치하는 문자가 있는지 검사하는 함수
  • char *str 검색할 문자열
  • int c 존재하는지 확인할 문자(아스키 값으로 들어감)
  • 첫 번째 매개변수 str의 문자열에서 두 번째 매개변수로 들어온 c가 존재하는지 검사하고, 문자가 존재하면 해당 문자가 존재하는 곳의 포인터를 반환하고, 존재하지 않으면 널 포인터를 반환
  • https://blockdmask.tistory.com/389

16. ft_strrchr

#include "libft.h"

char    *ft_strrchr(const char *s, int c)
{
    int i;

		i = 0;
    while (s[i])
			i++;
    while (i >= 0)
    {
			if (s[i] == (char) c)
				return ((char *)(s + i));
			i--;
    }
    return (NULL);
}
  • 문자열에서 문자를 검색하되 가장 마지막으로 나타난 위치를 찾는 함수

17. ft_strncmp

#include "libft.h"

int ft_strncmp(const char *s1, const char *s2, size_t n)
{
    size_t  i;

		i = 0;
    while (i < n && (s1[i] != '\0' || s2[i] != '\0'))
    {
			if (s1[i] != s2[i])
				return ((unsigned char)(s1[i]) - (unsigned char)(s2[i]));
			i++;
    }
    return (0);
}
  • const char *s1 비교할 문자열 1
  • const char *s2 비교할 문자열 2
  • size_t n 비교할 문자열 길이
  • 매개변수로 들어온 두 개의 문자열을 비교하여 문자열이 완전히 같으면 0을 반환, 다르면 음수 혹은 양수를 반환하는 함수
  • -1, 1은 매개변수로 들어온 문자열들을 비교하다가 다른 문자가 나왔을 때 그 문자의 아스키코드 값에 의해서 정해진다.
    • s1 > s2 : 양수 반환
    • s1 < s2 : 음수 반환
    • s1 == s2 : 0 반환
  • 세 번째 매개변수 n에 0을 넣은 경우 결과는 항상 0이 나오고, -1을 넣은 경우 unsigned int 값에서 언더플로우가 일어나기 때문에 최대값이 들어가므로 매개변수로 들어온 문자열을 끝까지 비교를 하게 된다. (여기서 끝까지 비교한다는 것은 다른 것이 나올 때까지 비교하거나 끝을 감지했을 때까지)
  • https://blockdmask.tistory.com/391

18. ft_memchr

#include "libft.h"

void    *ft_memchr(const void *s, int c, size_t n)
{
    size_t  i;

		i = 0;
    while (i < n)
    {
			if (((unsigned char *)s)[i] == (unsigned char)c)
				return (&((char *)s)[i]);
			i++;
    }
    return (0);
}
  • 메모리 블록에서 문자를 찾는 함수
  • s가 가리키는 메모리의 처음 n 바이트 중에서 처음으로 c와 일치하는 값의 주소를 리턴한다.
  • const void *s 검색을 수행할 부분의 시작 주소
  • int c 찾을 값으로, int로 값이 전달되지만 함수 내부적으로는 한 바이트씩 비교하기 때문에 이 값은 unsigned char로 변환되어 사용된다.
  • size_t n 검색을 시작한 부분부터 검색을 수행할 만큼의 바이트 수
  • 메모리 블록에서 n 바이트 내에 c와 일치하는 값이 있다면 그곳의 주소를 리턴하고, 찾지 못한다면 NULL을 리턴한다.
  • https://modoocode.com/92

19. ft_memcmp

#include "libft.h"

int ft_memcmp(const void *s1, const void *s2, size_t n)
{
    size_t  i;

		i = 0;
    while (i < n)
    {
			if (*(unsigned char *)(s1 + i) != *(unsigned char *)(s2 + i))
				return (*(unsigned char *)(s1 + i) - *(unㄹsigned char *)(s2 + i));
			i++;
    }
    return (0);
}
  • 두 개의 메모리 블록을 비교하는 함수
  • s1이 가리키는 처음 n 바이트의 데이터와 s2가 가리키는 처음 n 바이트의 데이터를 비교하여 이들이 같다면 0을 리턴하고, 다르다면 0이 아닌 값을 리턴한다.
  • 매개변수
    • const void *s1 메모리 블록을 가리키는 포인터
    • const void *s2 메모리 블록을 가리키는 포인터
    • size_t n 비교할 바이트 수
  • 두 개의 메모리 블록의 관계에 따라 아래와 같이 정수 값을 리턴한다.
    • 만일 두 메모리 블록이 정확히 같다면 0을 리턴
    • 만일 두 메모리 블록이 다를 경우, s1과 s2가 가리키는 메모리 블록에서 앞에서부터 처음으로 다른 바이트를 살펴보는데, 그 바이트를 unsigned char로 해석하였을 때, 그 값이 s1이 더 크면 0보다 큰 값을, 아니면 0보다 작은 값을 리턴

20. ft_strnstr

#include "libft.h"

char    *ft_strnstr(const char *haystack, const char *needle, size_t len)
{
    size_t  i;
    size_t  j;

		if (!haystack || !needle)
			return (NULL);
    if (!needle || !needle[0])
			return ((char *)haystack);
    i = 0;
    while (haystack[i] && i < len)
    {
			j = 0;
			while (haystack[i + j] && needle[j] && \
					i + j < len && haystack[i + j] == needle[j])
				j++;
			if (!needle[j])
				return ((char *)(haystack + i));
			i++;
    }
    return (NULL);
}
  • 문자열 내에서 부분 문자열을 탐색하는 함수
  • 종료 전까지의 문자들 중 haystack 문자열 내에서 찾은 needle 문자열 중 첫 번째로 나온 결과를 찾는다. 문자열은 최대 len의 수까지만 탐색한다.
  • 문자열들은 \0을 만나면 더 이상 찾지 않는다.
  • const char *haystack 큰 문자열, 탐색할 전체 문자열
  • const char *needle 작은 문자열, 추출해 낼 부분 문자열
  • size_t len haystack 문자열 내에서 탐색할 최대 범위
  • char * 형 데이터로 리턴
    • needle 문자열이 비어있을 경우, haystack 문자열을 리턴
    • needle 문자열이 haystack 문자열 내에 없는 경우 NULL을 리턴
    • 위의 경우들이 아니라면, needle 문자열을 찾은 문자열 중 첫 글자를 가리키는 포인터를 리턴
  • https://velog.io/@mjung/function-strstr-strnstr

21. ft_atoi

#include "libft.h"

int ft_atoi(const char *str)
{
    int     minus;
    long    res;

		minus = 1;
    res = 0;
    while ((9 <= *str && *str <= 13) || *str == ' ')
			++str;
    if (*str == '+' || *str == '-')
			if (*str++ == '-')
				minus *= -1;
    while ('0' <= *str && *str <= '9')
    {
			res = res * 10 + (*str++ - '0');
			if (res < 0)
				return ((minus + 1) / -2);
    }
    return (res * minus);
}
  • a - to - i로 생각. a = char(ASCII), i = int. 즉, char to integer
  • char 타입을 int 타입으로 변경하는 함수
  • 리턴 값 1. atoi("문자") : 문자가 맨 처음 나왔기 때문에 0을 반환 2. atoi("숫자") : 숫자를 반환 3. atoi("숫자+문자") : 문자가 나오기 전까지의 숫자를 반환 4. atoi("문자+숫자") : 문자가 바로 나오기 때문에 0을 반환
  • https://blockdmask.tistory.com/331

22. ft_calloc

#include "libft.h"

void    *ft_calloc(size_t count, size_t size)
{
    void    *ptr;

		ptr = (void *)malloc(count * size);
    if (ptr == 0)
			return (0);
    ft_memset(ptr, 0, count * size);
    return (ptr);
}
  • malloc 함수와 같은 기능을 지닌다. size 크기의 변수를 count 개만큼 저장할 수 있는 메모리 공간을 할당하라는 의미를 갖는다.
  • malloc함수와 calloc함수의 차이점!
    • malloc은 할당된 공간의 값을 바꾸지 않는다.
    • calloc은 할당된 공간의 값을 모두 0으로 바꾼다.
    • 배열을 할당하고 모두 0으로 초기화 할 필요가 있을 경우 calloc을 사용

23. ft_strdup

#include "libft.h"

char    *ft_strdup(const char *s1)
{
    char    *str;
    int     i;
    int     len;

		i = 0;
    len = ft_strlen(s1);
    str = (char *)malloc(sizeof(char) * (len + 1));
    if (str == 0)
			return (0);
    while (i < len)
    {
			str[i] = s1[i];
			i++;
    }
    str[i] = '\0';
    return (str);
}
  • 문자열 복사 함수. 문자열 s1을 복사하고, 복사된 문자열을 가리키는 포인터를 반환한다.
  • 문자를 복사할 공간을 확보하기 위해서 내부적으로 메모리 할당 및 검사를 수행한다.
  • strdup 함수 내부에서 malloc 함수 호출로 메모리를 할당하기 때문에 사용자는 free 등을 통해 반환된 char 포인터를 해제해주어야 한다.
  • 에러가 발생하거나 할당할 메모리가 부족할 때 NULL을 반환한다.

<Part 2>

24. ft_substr

#include "libft.h"

char    *ft_substr(char const *s, unsigned int start, size_t len)
{
    size_t  i;
    size_t  j;
    char    *str;

		if(!s)
			return(NULL);
		str = (char *)malloc(sizeof(*s) * (len + 1));
    if (!str)
			return (NULL);
    i = 0;
    j = 0;
    while (s[i])
    {
			if (i >= start && j < len)
			{
				str[j] = s[i];
				j++;
			}
			i++;
    }
    str[j] = 0;
    return (str);
}
  • malloc(3)를 사용해 할당하고 문자열 's'에서 하위 문자열을 반환하는 함수. 하위 문자열은 인덱스 'start'에서 시작되며 최대 크기 'len'
  • 매개 변수
    • 원본 문자열
    • 문자열 s에 있는 하위 문자열의 시작점
    • 하위 문자열의 길이
  • 반환 값
    • 잘라낸 문자열, 실패시 NULL 반환
  • https://wonillism.tistory.com/165

25. ft_strjoin

#include "libft.h"

char    *ft_strjoin(char const *s1, char const *s2)
{
    char    *str;
    size_t  i;
    size_t  j;

		if (!s1 || !s2)
			return (NULL);
    str = (char *)malloc(sizeof(*s1) * (ft_strlen(s1) + ft_strlen(s2) + 1));
    if (!str)
			return (NULL);
    i = 0;
    j = 0;
    while (s1[i])
    {
			str[j++] = s1[i];
			i++;
    }
	  i = 0;
    while (s2[i])
    {
			str[j++] = s2[i];
			i++;
    }
    str[j] = 0;
    return (str);
}
  • malloc(3)를 사용해 할당하고 s1과 s2 문자열을 연결한 새 문자열을 반환하는 함수
  • 매개변수
    • 접두사 문자열
    • 접미사 문자열
  • 반환 값
    • 이어 붙인 새 문자열, 실패 시 NULL 반환

26. ft_strtrim

#include "libft.h"

int char_in_set(char c, char const *set)
{
    size_t  i;

		i = 0;
    while (set[i])
    {
			if (set[i] == c)
				return (1);
			i++;
    }
    return (0);
}

char    *ft_strtrim(char const *s1, char const *set)
{
    char    *str;
    size_t  i;
    size_t  start;
    size_t  end;

		start = 0;
		while (s1[start] && char_in_set(s1[start], set))
			start++;
		end = ft_strlen(s1);
		while (end > start && char_in_set(s1[end - 1], set))
			end--;
		str = (char *)malloc(sizeof(*s1) * (end - start + 1));
		if (!str)
			return (NULL);
		i = 0;
		while (start < end)
			start[i++] = s1[start++];
		str[i] = 0;
		return (str);
}
  • malloc(3)를 사용해 할당하고 문자열의 처음과 끝에서 'set'에 지정된 문자가 제거된 's1' 복사본을 반환하는 함수
  • 매개 변수
    • 원본 문자열
    • 제거할 참조 문자열
  • 반환 값
    • s1에서 찾은 set에 포함된 문자들을 양 끝에서 제거한 후 결과 문자열 반환, 할당 실패 시 NULL 반환.
  • 주의해야 할 점!
    • 원본 문자열 전체가 set에 포함되는 문자일 때
    • 우선 앞에서 문자들을 지우고, '\0'을 제외하고 뒷부분부터 탐색을 한다. 이때 end 값이 start 보다 작아진다면 원본 문자열에 지워야 할 문자를 제외하면 없다는 뜻이므로, '\0' 값을 할당하여 반환한다.
    • 그렇지 않으면 지우고 난 후 end - start + 1 하여 '\0'값 포함한 길이만큼 할당하여 결과를 복사하여 반환한다.

27. ft_split

#include "libft.h"

// s 문자열에서 n+1만큼의 저장 공간을 할당하고 문자열을 저장하여 리턴
char    *ft_strndup(const char *s, size_t n)
{
    size_t  i;
    char    *str;

		i = 0;
    str = NULL;
    if (n == 0)
			return (NULL);
    str = (char *)malloc(sizeof(char) * (n + 1));
    if (str == 0)
			return (NULL);
    while (i < n)
    {
			str[i] = s[i];
			i++;
    }
    str[i] = '\0';
    return (str);
}

// list 내부의 할당된 저장 공간들을 모두 free해주고 list도 free
char    **ft_freeall(char **list)
{
    size_t  i;

		i = 0;
		while (list[i])
		{
			free(list[i]);
			i++;
		}
		free(list);
		return (NULL);
}

// 문자열 s를 c 문자를 기준으로 나누었을 때 총 몇 개의 저장 공간이 필요한지 구하는 함수
size_t  ft_wordcount(char const *s, char c)
{
		size_t  size;
		size_t  i;
		
		i = 0;
		size = 0;
		while (s[i] != '\0')
		{
			if ((i == 0 && s[i] != c) || \
			(s[i] == c && s[i + 1] != '\0' && s[i + 1] != c))
				size++;
			i++;
		}
    return (size);
}

char    **ft_split(char const *s, char c)
{
    char    **list;
    size_t  i;
    size_t  j;
    size_t  temp;

		i = 0;
    j = 0;
    list = (char **)malloc(sizeof(char *) * (ft_wordcount(s, c) + 1));
    if (!list)
			return (NULL);
    while (i < ft_wordcount(s, c) && s[j] != '\0')
    {
			while (s[j] == c)
				j++;
			save = j;
			while (s[j] != c && s[j] != '\0')
				j++;
			list[i] = ft_strndup(&s[temp], j - temp);
			if (list[i++] == 0)
				return (ft_freeall(list));
    }
    list[i] = NULL;
    return (list);
}
  • malloc(3)로 할당하고 문자 'c'를 구분 기호로 사용하여 's'를 분할하여 얻은 문자열 배열을 반환하는 함수. 배열을 NULL 포인터로 종료해야 함.
  • 매개 변수
    • 분할할 문자열
    • 구분 기호 문자
  • 반환 값
    • 분할한 새 문자열 배열, 할당 실패 시 NULL 반환
    • 문자열 s를 c 문자 기준으로 나누어 배열의 각 칸에 저장하고 마지막 배열은 NULL로 채워 반환
  • 주의사항
    • 배열의 각 칸에 정보를 저장하다가 할당에 실패해 함수를 종료할 때 여태 malloc으로 할당했던 각 배열 칸마다 저장 공간, 배열 자체의 저장 공간을 모두 free시켜주어야 함. (메모리 누수 방지)
    • 문자열의 첫 시작 부분이 c라면 그 부분을 넘겨주어야 하고, 첫 시작 부분이 c가 아니라면 만들어야 하는 문자열의 수를 1 늘려주어야 한다.

28. ft_itoa

#include "libft.h"

static int  ft_abs(int nbr)
{
    if (nbr < 0)
			return (-nbr);
    else
			return (nbr);
}

static void ft_strrev(char *str)
{
    size_t  len;
    size_t  i;
    char    tmp;

		len = ft_strlen(str);
    i = 0;
    while (i < len / 2)
    {
			tmp = str[i];
			str[i] = str[len - i - 1];
			str[len - i - 1] = tmp;
			i++;
    }
}

char    *ft_itoa(int n)
{
    char    *str;
    int     minus;
    size_t  len;

		minus = (n < 0);
    str = ft_calloc(11 + minus, sizeof(*str));
    if (!str)
			return (NULL);
    if (n == 0)
			str[0] = '0';
    len = 0;
    while (n != 0)
    {
			str[len++] = '0' + ft_abs(n % 10);
			n = (n / 10);
    }
    if (minus)
			str[len] = '-';
    ft_strrev(str);
    return (str);
}
  • malloc(3)를 사용하여 할당하고 인수로 받은 정수를 나타내는 문자열을 반환하는 함수. 음수는 반드시 처리
  • 매개변수
    • 변환할 정수
  • 반환 값
    • 정수를 나타내는 문자열, 할당 실패 시 NULL 반환

29. ft_strmapi

#include "libft.h"

char    *ft_strmapi(char const *s, char (*f)(unsigned int, char))
{
    char    *str;
    size_t  i;

		str = ft_strdup(s);
    if (!str)
			return (NULL);
    i = 0;
    while (str[i])
    {
			str[i] = (*f)(i, str[i]);
			i++;
    }
    return (str);
}
  • 함수 포인터를 사용하여 인자로 들어온 문자열에 함수를 적용하는 함수
  • 매개변수
    • char const *s 적용당하는 문자열
    • char (*f)(unsigned int, char)  문자열에 속한 문자들에 적용할 함수
  • 리턴 값
    • 적용된 문자로 생성 된 새로운 문자열
    • 할당이 실패하면 NULL을 반환
  • https://velog.io/@meong9090/42seoul-ftstrmapi는-어떤-함수일까

30. ft_striteri

#include "libft.h"

void    ft_striteri(char *s, void (*f)(unsigned int, char*))
{
    int i;

		if (!s || !f)
			return ;
		i = 0;
    while (s[i])
    {
			f(i, &s[i]);
			i++;
    }
}
  • 문자열 s를 순회하며 각 요소에 함수 f를 적용시키는 함수
  • 설명: 인수로 전달된 문자열의 각 문자에 함수 f를 적용하고 인덱스를 첫 번째 인수로 전달합니다. 각 문자는 주소를 통해 f로 전달되어 필요할 경우 수정됩니다.
  • 매개변수
    • char *s 함수 f를 적용시킬 문자열
    • (*f) 문자열 s에 적용할 함수의 함수 포인터
  • 반환 값 X
  • 주의사항: 함수 f에는 현재 문자열 요소의 인덱스값과 주소값을 전달해줌

31. ft_putchar_fd

#include "libft.h"

void    ft_putchar_fd(char c, int fd)
{
		if (fd < 0)
			return ;
    write(fd, &c, 1);
}
  • 문자 c, 파일 디스크립터 fd를 사용해 write 함수로 출력하는 함수
  • 매개변수
    • char c 출력할 문자
    • int fd 정수값으로 받아오는 파일 디스크립터
  • 반환 값 X
  • 주의사항
    • fd는 파일 디스크립터로 정수형으로 받아옴
    • 프로세스가 특정 파일에 접근하기 위한 추상적인 키. 어떤 파일인지를 숫자로 구분하며 음수 X
    • 0(표준 출력), 1(표준 입력), 2(표준 에러), 3부터 사용된다.
    • write(파일 디스크립터, 문자열 시작 주소, 바이트 수)

32. ft_putstr_fd

#include "libft.h"

void    ft_putstr_fd(char *s, int fd)
{
    if (!s)
			return ;
    write(fd, s, ft_strlen(s));
}
  • 문자열 s를 주어진 파일 디스크립터를 사용해 write 함수로 출력하는 함수
  • 매개변수
    • char *s 출력할 문자열
    • int fd 파일 디스크립터
  • 반환 값 X

33. ft_putendl_fd

#include "libft.h"

void    ft_putendl_fd(char *s, int fd)
{
    const char  n1 = '\n';

		if (fd < 0)
			return ;
		write(fd, s, ft_strlen(s));
    write(fd, &n1, 1);
}
  • 문자열 s를 주어진 파일 디스크립터와 write 함수로 출력하고 줄바꿈을 출력하는 함수
  • 매개변수
    • char *s 출력할 문자열
    • int fd 파일 디스크립터
  • 반환 값 X

34. ft_putnbr_fd

#include "libft.h"

void    ft_putnbr_fd(int n, int fd)
{
    char    str;
		
		if (fd < 0)
			return ;
    if (n == -2147483648)
    {
			write(fd, "-2147483648", 11);
			return ;
    }
    else if (n < 0)
    {
			write(fd, "-", 1);
			n = n * -1;
    }
    if (n >= 10)
    {
			ft_putnbr_fd(n / 10, fd);
			str = '0' + (n % 10);
    }
		else if (n < 10)
			str = '0' + n;
		write(fd, &str, 1);
}
  • int형 정수를 받아와 주어진 fd와 write 함수를 사용해 출력하는 함수
  • 매개변수
    • int n 출력할 정수
    • int fd 파일 디스크립터
  • 반환 값 X
  • 주의사항
    • write 함수는 int형을 바로 출력할 수 없으므로 ascii 코드를 활용해 출력해 주어야함
    • 재귀함수를 통해 나중에 호출된 함수가 먼저 실행되는 방식으로 하나씩 출력
    • int형의 min max를 잘 생각해서 구현
profile
FE 👩🏻‍💻

0개의 댓글