[Libft] C 언어 라이브러리 구현_Part1_문자 판별 + 변환 관련 함수

2021. 5. 20. 03:44·IT/42Seoul

혹시나 문제가 된다면 바로 비공개 처리하겠습니다. 지적이나 댓글 환영합니다!

 

이번 포스팅에서는 문자 판별 + 변환 함수에 관한 내용을 정리하겠다.

 

참고로, 내가 정의한 libft.h 헤더에는 <unistd.h>와 <stdlib.h>가 include 되어있다. 따라서 libft.h를 호출하면, 따로 정의하지 않고도 <unistd.h> 에 정의된 size_t 타입과 <stdlib.h>의 malloc/free를 사용할 수 있다.

 

 

 

 

 

(1) isalpha : 문자가 알파벳인지 판별

- is + alphabet

 

- 매뉴얼(영문번역) :
        이름 : isalpha -- 알파벳 문자인지 판별
        라이브러리 : 표준 C 라이브러리 (libc, -lc)
        시놉시스 :
                   #include <ctype.c>
                   int isalpha(int c);

        설명 :

                   isalpha() 함수는 isupper() 또는 islower()이 참이 되게 하는 문자를 판별한다.

                   인자로 전달된 값은 (unsigned char) 형으로 표현되거나 EOF의 값으로 표현되어야한다.
        리턴값 : 문자 판별 값이 false일 경우 0을 리턴하며, 문자 판별 값이 true일 경우 0이 아닌 값을 리턴한다.

 

 


- 구현 코드 예시 :

1
2
3
4
5
6
7
8
9
#include "libft.h"
 
int        ft_isalpha(int c)
{
    if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
        return (1);
    return (0);
}
 
Colored by Color Scripter
cs

- '0이 아닌 값'을 리턴하므로, 사실 어떤 값을 리턴해도 상관없다.

  그렇지만 ctype헤더에서 islapha()를 직접 import해서 출력한 결과, 1과 0으로 결과값이 나오는 것을 확인하고 그대로 구현하였다.

- 알파벳을 판별하므로, 소문자 또는 대문자인 것을 판별하였다.

 

- 참고) 0이 아닌 값 중 어떤 값을 리턴해도 상관없는 이유

더보기

C언어에서는 0을 거짓으로, 그 이외의 값을 모두 참으로 사용한다.

따라서 if (isalpha(c))를 실행할 경우, 어떤 값이 리턴되더라도 0만 아니면 if 문의 조건이 참이되어 조건문 속 코드가 실행된다.

 

 

 

 

 

(2) isdigit : 문자가 숫자인지 판별

- is + digit

 

- 매뉴얼(영문번역) :
        이름 : isdigit -- 10진수-숫자 문자인지 판별
        라이브러리 : 표준 C 라이브러리 (libc, -lc)
        시놉시스 :
                   #include <ctype.c>
                   int isdigit(int c);

        설명 :

                   isdigit() 함수는 10진수 숫자인 문자를 판별한다. 그것들은 언어와 상관없이, '0' ~ '9'의 문자만 포함한다.

                   인자로 전달된 값은 (unsigned char) 형으로 표현되거나 EOF의 값으로 표현되어야한다.
        리턴값 : 문자 판별 값이 false일 경우 0을 리턴하며, 문자 판별 값이 true일 경우 0이 아닌 값을 리턴한다.

 

 


- 구현 코드 예시 :

1
2
3
4
5
6
7
8
9
#include "libft.h"
 
int        ft_isdigit(int c)
{
    if (c >= '0' && c <= '9')
        return (1);
    return (0);
}
 
cs

- 10진수 숫자 문자 '0' ~ '9' 사이의 값이라면 1을 리턴하고, 그렇지 않으면 0을 리턴한다. 

 

 

 

 

 

(3) isalnum : 문자가 알파벳이나 숫자인지 판별

- is + alphabet + num

 

- 매뉴얼(영문번역) :
        이름 : isalnum -- 알파벳 혹은 숫자 문자인지 판별
        라이브러리 : 표준 C 라이브러리 (libc, -lc)
        시놉시스 :
                   #include <ctype.c>
                   int isdigit(int c);

        설명 :

                   isalnum() 함수는 isalpha() 또는 isdigit()이 참이 되게 하는 문자를 판별한다.

                   인자로 전달된 값은 (unsigned char) 형으로 표현되거나 EOF의 값으로 표현되어야한다.
        리턴값 : 문자 판별 값이 false일 경우 0을 리턴하며, 문자 판별 값이 true일 경우 0이 아닌 값을 리턴한다.

 

 


- 구현 코드 예시 :

1
2
3
4
5
6
7
8
9
#include "libft.h"
 
int        ft_isalnum(int c)
{
    if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
            || (c >= '0' && c <= '9'))
        return (1);
    return (0);
}
Colored by Color Scripter
cs

- 알파벳 혹은 숫자 둘 중 하나라면 1을 리턴하고, 그렇지 않으면 0을 리턴한다.

 

 

 

 

 

(4) isascii : 문자가 아스키 문자인지 판별

- is + ASCII

 

- 매뉴얼(영문번역) :
        이름 : isascii -- ASCII 문자인지 판별
        라이브러리 : 표준 C 라이브러리 (libc, -lc)
        시놉시스 :
                   #include <ctype.c>
                   int isascii(int c);

        설명 :

                   isacii() 함수는 주어진 문자가 ASCII 문자(0 ~ 0177(8진수))인지 판별한다.

 

 


- 구현 코드 예시 :

1
2
3
4
5
6
7
8
9
#include "libft.h"
 
int        ft_isascii(int c)
{
    if (c >= 0 && c <= 127)
        return (1);
    return (0);
}
 
cs

- 8진수 0177을 10진수로 변환하면 127이다. 따라서 10진수로 0 ~ 127 범위 내의 값인지 판별한다.

- 아스키 문자 범위에 포함되어 있다면 1을 리턴하고, 그렇지 않으면 0을 리턴한다.

 

 

 

 

 

(5) toupper : 문자를 대문자로 변환

- to + Uppercase

 

- 매뉴얼(영문번역) :
        이름 : toupper -- 알파벳 소문자를 알파벳 대문자로 변환
        라이브러리 : 표준 C 라이브러리 (libc, -lc)
        시놉시스 :
                   #include <ctype.c>
                   int toupper(int c);

        설명 :

                  toupper() 함수는 소문자를 그에 대응하는 대문자로 변환한다.

                  인자로 전달된 값은 (unsigned char) 형으로 표현되거나 EOF의 값으로 표현되어야한다.
        리턴값 : 인자가 소문자일 경우, 그에 대응하는 대문자가 있다면 그것을 반환한다.

                    그렇지 않으면, 바뀌지 않은 채의 인자가 반환된다.

 

 


- 구현 코드 예시 :

1
2
3
4
5
6
7
8
9
#include "libft.h"
 
int        ft_toupper(int c)
{
    if (c >= 'a' && c <= 'z')
        c -= 32;
    return (c);
}
 
cs

- 아스키코드 상에서 대문자와 소문자의 차이값은 32이다. 그것도 소문자가 아스키코드값이 더 크다.

- 따라서 매개변수로 받은 인자가 소문자일 경우, 인자에서 32를 빼준 후 리턴해준다. 

 

- 참고) 아스키 코드란? 

더보기

컴퓨터는 0과 1 숫자 밖에 모르기 때문에 문자도 숫자로 기억한다. 이때, 어떤 숫자와 어떤 문자를 대응시키는 가에 따라 여러가지 인코딩 방식이 있는데 통상 아스키 코드 방식을 많이 사용한다.

 

아스키 코드(ASCII Table)는 0번부터 127번까지만 사용한다. 127번 이후 코드를 사용했던 적도 있었는데 이는 표준이 아니며, 운영체제마다 다른 코드(문자)를 배치했기 때문에 호환이 되지 않는다. 윈도우즈 운영 체제는 현재 128번부터 255번 사이에 포함된 문자를 출력하려는 시도에 대하여 물음표(?)를 출력해서 사용하면 안된다는 것을 알려준다. 128번과 255번 문자는 물음표는 아니지만 사용할 수 없는 문자이다.

 

- 참고) 아스키 코드 표

더보기

제어 문자는 0번부터 31번 문자까지를 모두 포함하지만, 중간에 공백으로 사용되는 문자들이 있어 9번부터 13번 까지를 공백 문자로 처리했다. 표 마지막에 있는 DEL 문자는 제어문자이므로 갈색이다.

 

이미지 출처 : https://shaeod.tistory.com/228

 

 

 

 

 

(6) tolower : 문자를 소문자로 변환

- to + Lowercase

 

- 매뉴얼(영문번역) :
        이름 : tolower -- 알파벳 대문자를 알파벳 소문자로 변환
        라이브러리 : 표준 C 라이브러리 (libc, -lc)
        시놉시스 :
                   #include <ctype.c>
                   int tolower(int c);

        설명 :

                  tolower() 함수는 대문자를 그에 대응하는 소문자로 변환한다.

                  인자로 전달된 값은 (unsigned char) 형으로 표현되거나 EOF의 값으로 표현되어야한다.
        리턴값 : 인자가 대문자일 경우, 그에 대응하는 소문자가 있다면 그것을 반환한다.

                    그렇지 않으면, 바뀌지 않은 채의 인자가 반환된다.

 

 


- 구현 코드 예시 :

1
2
3
4
5
6
7
8
9
#include "libft.h"
 
int        ft_tolower(int c)
{
    if (c >= 'A' && c <= 'Z')
        c += 32;
    return (c);
}
 
cs

- 아스키코드 상에서 대문자와 소문자의 차이값은 32이다. 그것도 소문자가 아스키코드값이 더 크다.

- 따라서 매개변수로 받은 인자가 대문자일 경우, 인자에서 32를 더해준 후 리턴해준다. 

 

 

 

 

 

(7) atoi : 문자 변환 함수

- Alphabet to Integer : 문자를 정수로 변환

- 매뉴얼(영문번역) :
        이름 : atoi -- ASCII 문자열을 정수로 변환한다
        라이브러리 : 표준 C 라이브러리 (libc, -lc)
        시놉시스 :
                   #include <stdlib.h>
                   int atoi(const char *str);
        설명 : atoi() 함수는 str이 가르키는 문자열의 앞 부분을 정수 표현으로 변환한다
        리턴값 : 문자열 str을 int형 정수로 변환한 값

 

 


- 구현 코드 예시 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "libft.h"
 
static int    is_space(char c)
{
    if (c == ' ' || c == '\t' || c == '\v'
            || c == '\r' || c == '\f' || c == '\n')
        return (1);
    return (0);
}
 
static int    is_operater(char c)
{
    if (c == '+' || c == '-')
        return (1);
    return (0);
}
 
static int    check_long_long(unsigned long long nb, int sign)
{
    if (nb > 0 && (nb - 1 > 9223372036854775807) && sign == -1)
        return (0);
    if (nb > 9223372036854775807 && sign == 1)
        return (-1);
    return (1);
}
 
int            ft_atoi(const char *str)
{
    unsigned long long    nb;
    int                    i;
    int                    sign;
    int                    ret;
 
    i = 0;
    sign = 1;
    while (is_space(str[i]))
        i++;
    if (is_operater(str[i]))
    {
        if (str[i] == '-')
            sign *= -1;
        i++;
    }
    nb = 0;
    while (str[i] >= '0' && str[i] <= '9')
    {
        if ((ret = check_long_long(nb, sign)) != 1)
            return (ret);
        nb *= 10;
        nb += str[i] - '0';
        i++;
    }
    return (sign * (int)nb);
}
 
Colored by Color Scripter
cs

- 인자로 받은 문자열을 int 형 숫자로 변환한다.

- 문자열에 int형 최솟값(INT_MIN = -2147483648)이 들어온 경우는 따로 예외처리 해주지 않았다. INT_MAX(2147483647) 값을 초과하므로 자동으로 오버플로우가 발생하여 INT_MIN 값으로 결과가 처리되기 때문이다.

- 앞에 공백이 나오는 부분은 while문으로 인덱스를 계속 증가시켜 지나간다. 그리고 다음에 나오는 부호를 확인한다.

- 문자의 범위가 '0' ~ '9'인 숫자 범위 사이인 경우인 동안, 숫자 변환을 계속한다.

- 문자의 범위가 '0' ~ '9'의 범위가 더이상 아닌 경우(다른 문자나 널 문자가 나온 경우), while문을 중단하고 현재 부호값과 int형으로 캐스팅한 숫자값을 곱하여 결과값인 정수를 리턴한다. 이때 따로 오버플로우는 처리해주지 않는다.

 

 

- 내가 만든 check_long_long 함수의 역할

더보기

원래 atoi함수에서는, 숫자가 long long 범위를 넘어갈 경우, 0 혹은 -1 을 반환하도록 한다.

부호가 양수일 경우는 -1, 음수일 경우에는 0을 리턴한다.

이 함수는 주어진 문자열이 long_long형을 가질 숫자 문자열인지를 판별한다.

 

원래 atoi함수가 int형을 리턴하므로 이러한 구현은 필수적이지는 않으며, 그저 권장사항이지만, 기존의 함수를 완벽한 구현하기 위하여 구현하였다.

따라서 nb를 unsigned long long으로 선언하였다. 그리고 주어진 문자열에서 부호를 뺀 숫자부분을 nb에 저장하여, 부호와 함께 long long 범위를 초과하는지를 체크하여, atoi함수와 같은 동작을 수행하도록하였다.

 

왜인지 모르겠지만 비교연산자 "=="는 long long 범위까지의 비교만 가능한 것 같았다.(아니면 컴파일 에러)

그래서 nb가 long long min인지 보려는 경우에는, 부호를 뺀 양수값으로 만들어 sign값과 함께 확인해야하는데, 이 경우 long long max의 범위를 초과하여 컴파일 에러가 났다.

따라서 if 문의 조건을 nb > 0 && (nb - 1 > long long max)로 수정하였다.

이때 nb > 0 의 조건을 넣지 않으면 언더플로우가 나서 전체적인 결과값에 오류가 난다.

 

- 참고) 숫자 변환 알고리즘

더보기

먼저 숫자값을 저장할 int 형 변수 nb를 0으로 초기화해준다.

현재 인덱스에 나오는 숫자형 문자에서 계속 '0'을 빼서 각 자리 문자를 한자리 숫자로 만들어 주고, nb 변수에 이를 더한다. 다음 인덱스로 넘어갈 때마다 10을 곱해가며 문자가 종료될 때까지 이를 계속한다.

 

- 참고) static 함수란 무엇인가

더보기

static을 붙인 정적함수는 해당 파일에서만 사용할 수 있다. 정적 함수를 사용하면 같은 이름을 가진 함수를 파일마다 만들 수 있다. 따라서 정적 함수는 기능이 여러 파일로 분리되어 있을 때, 각 파일 안에서만 사용하는 기능을 구현할 수 있다.

 

libft 과제에서는 과제함수 이외의 함수가 해당 파일 내에서만 컴파일되도록하기 위해, 헤더파일에 포함되지 않는 함수에는 static을 사용할 것을 규칙으로 하고 있다.

 

 

 

 

 

 

참고 자료 출처 :

더보기

https://dojang.io/mod/page/view.php?id=130 

 

C 언어 코딩 도장: 18.4 if 조건문의 동작 방식 알아보기

C 언어에서 if는 0일 때 거짓, 0이 아닐 때 참으로 동작합니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요. if_2.c #include int main() { if (2) // 0이 아니므로 참 printf("참\n"); else printf("거

dojang.io

https://shaeod.tistory.com/228

 

ASCII Table - 아스키 코드표

(아스키코드를 알면 C/C++이나 Java 등으로 문자열 함수를 다루거나 파일 함수를 다룰때 도움이 됩니다.) 컴퓨터는 0과 1 숫자 밖에 모르기 때문에 문자도 숫자로 기억합니다. 이때, 어떤 숫자와 어

shaeod.tistory.com

https://dojang.io/mod/page/view.php?id=691 

 

C 언어 코딩 도장: 79.3 정적 함수 사용하기

이번에는 정적 함수를 알아보겠습니다. 다음 내용을 프로젝트 디렉터리에 print.c로 저장하세요(반드시 프로젝트에 포함해야 합니다). print.c #include void print() // print.c에서 print 함수 선언 및 정의 {

dojang.io

 

'IT > 42Seoul' 카테고리의 다른 글

[Libft] C 언어 라이브러리 구현_Part2_추가함수 구현2  (0) 2021.05.23
[Libft] C 언어 라이브러리 구현_Part2_추가함수 구현1  (0) 2021.05.23
[Libft] C 언어 라이브러리 구현_Part1_malloc을 사용한 함수  (0) 2021.05.20
[Libft] C 언어 라이브러리 구현_Part1_문자열 관련 함수  (0) 2021.05.20
[Libft] C 언어 라이브러리 구현_Part1_mem관련 함수  (0) 2021.05.17
'IT/42Seoul' 카테고리의 다른 글
  • [Libft] C 언어 라이브러리 구현_Part2_추가함수 구현1
  • [Libft] C 언어 라이브러리 구현_Part1_malloc을 사용한 함수
  • [Libft] C 언어 라이브러리 구현_Part1_문자열 관련 함수
  • [Libft] C 언어 라이브러리 구현_Part1_mem관련 함수
남서아 (구 - 밥한그릇배따시게)
남서아 (구 - 밥한그릇배따시게)
학습하고 정리한 내용 중, 공유할만한 것들을 포스팅합니다. / 소프트웨어 학사 (2025년도 2월 졸업)
  • 남서아 (구 - 밥한그릇배따시게)
    남서아 기술블로그
    남서아 (구 - 밥한그릇배따시게)
  • 전체
    오늘
    어제
  • 공지사항

    • 개발자 정보 및 포트폴리오
    • 포스팅 목적
  • 링크

    • Portfolio
    • 분류 전체보기 (99) N
      • IT (59) N
        • 클라우드 & 인프라 (2)
        • CS 공부 (12)
        • 42Seoul (19)
        • 개발 언어 및 도구 (4)
        • 개발 환경 및 설치 (5)
        • 튜토리얼 및 가이드 (10) N
        • Data & AI (5)
        • ETC (2)
      • Experience (4)
      • English (32)
        • 회화 (5)
        • 자격증 공부 (26)
        • 후기 (1)
      • 근황 (4) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • hELLO· Designed By정상우.v4.10.3
남서아 (구 - 밥한그릇배따시게)
[Libft] C 언어 라이브러리 구현_Part1_문자 판별 + 변환 관련 함수
상단으로

티스토리툴바