ft_itoa 구현

yeonjkim·2021년 5월 22일
0

42seoul-libft

목록 보기
9/43

1. ft_itoa 용도

* integer to ascii. 

* 인자로 들어온 int형 숫자를 (char *)로 전환하는 함수.

2. ft_itoa 프로토타입

char	*ft_itoa(int n)

3. 구현 시 유의사항

* int n을 char *로 표현하기 위해서는 malloc() 함수가 필요하다.
--> 할당할 크기를 알기 위해서 n의 부호와 n의 길이를 구하는 것이 필수적.

* n이 -2147483648이라면 이에 *(-1)을 해 준 값은 int type의 오버플로우가 발생.
--> 이에 대한 예외처리가 필수. (다만 개인이 짠 코드에 따라 달라질 수 있음)

* 할당에 실패했을 시 NULL포인터를 반환.

* n이 음수냐, 양수냐에 따라 char *의 첫번째 값이 '-'냐 다른 숫자냐가 결정됨.

* n이 0일 때 주의하기.

4. 코드 구현

#include "libft.h"

static void                     ft_substitute(char *str, int len, int n)//할당한 str에 n을 변환한 값을 하나씩 집어넣는 함수
{
        int                     index;

        index = 0;
        if (n == 0)//n이 0일 때 0 집어넣기.
        {
                str[index] = '0';
        }
        while (n != 0)//n이 0이 아닐 때까지 str에 대입.
        {
                str[len - index - 1] = n % 10 + '0';
                n /= 10;
                index++;
        }
}

static int                      ft_len(int n, int *minus)//-부호를 제외한 n의 길이 구하는 함수. 리턴 값은 하나만 존재해야 하므로 minus의 주소를 인자로 받음.
{
        int                     len;

        len = 0;
        if (n < 0)
        {
                if (n == -2147483648)//n이 int형 min값일 때의 예외처리.
                {
                        *minus = 1;
                        return (10);//'-'를 제외한 int형 min값의 길이
                }
                else//n을 양수로 바꾸기.(부호 제외한 n의 길이 알기 위함)
                {
                        *minus = 1;
                        n = -n;
                }
        }
        else if (n == 0)//n이 0일 때 길이는 1
                return (1);
        while (n != 0)//길이 구하기
        {
                len++;
                n /= 10;
        }
        return (len);
}

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

        minus = 0;
        len = ft_len(n, &minus);
        if (!(str = (char*)malloc(sizeof(char) * (len + minus + 1))))
                return (NULL);//부호와 부호 제외한 길이 + NULL만큼 할당. 할당 실패 시 NULL	반환.
        str[len + minus] = '\0';//str의 마지막 index에 null 대입.
        if (n == -2147483648)//n이 int min일 때 예외처리.
        {
                str[10] = '8';//n에 -1곱하면 오버플로우가 생기므로 10번째 인덱스에 8 미리 대입
                n = 214748364;//8을 대입하고 남은 214748364.
                str[0] = '-';//음수라 str[0]에 -넣기.
                len--;//8을 대입했기 때문에 len을 하나 줄임.
        }
        else if (minus == 1)
        {
                str[0] = '-';//음수라 '-' 넣어주기
                n = -n;
        }
        ft_substitute(&str[minus], len, n);//ft_substitute함수의 인덱스가 0부터 시작하게 했기 때문에 str의 minus번째 인덱스를 인수로 전달.
        return (&str[0]);
}

6. 코드 구현 방법

  • ft_substitute : 할당된 str의 주소값과 len(길이), n을 인자로 받는 함수.
    n이 0일 때 str[0]에 0 대입, n이 0이 아닐 때까지 str의 len - index - 1번째 인덱스에 n을 10으로 나눈 나머지 + '0' 대입.

  • ft_len : int n과 int *minus를 인자로 받는 함수.
    n이 음수이면 minus에 1을 저장하고, 부호를 제외한 n의 길이를 리턴함.
    n이 0일 때, 길이는 0이 아닌 1이라는 것과 n이 int형 min값일 때 주의.

  • ft_itoa : int n을 아스키로 변환하는 함수.
    n이 양수일 때는 딱히 상관이 없지만, n이 음수일 때 할당해 줘야 하는 길이가 늘어남. 이를 minus 변수로 받음. str을 부호 제외 길이 + minus + 1(NULL 포함) 사이즈로 할당해 주고, 할당 실패 시 NULL 반환.

7. 구현 시 어려웠던 점

  • n이 0일 때와 int형 min값의 예외처리를 하는 데 고초를 겪음.

  • ft_len() 함수 내부에서 else if (n == 0)을 처음에 하지 않아 len이 0이 되는 경우가 발생. 이 경우 할당되지 않은 메모리 영역을 침범하여 abort가 떴었음.

  • c++과는 다르게 c에는 string type이 없어 char배열을 선언 이후 한번에 초기화할 수 없었음. 따라서 n이 int min이었을 때 str[0]에 '-', str[10]에 8을 넣고 n을 214748364로 저장하는 등의 잔꾀를 부림. 이 부분은 추후 수정할 용의가 있음.

0개의 댓글