man
을 한번씩 확인하여 설명을 읽고 함수의 원본과 동일한 프로토타입 및 기능을 수행하는 코드 작성 필요
//#include <ctype.h>
int ft_isalnum(int c)
- 알파벳인지 검사하는 함수
0
을 반환//#include <ctype.h>
int ft_isdigit(int c)
- 숫자인지 검사하는 함수
0
을 반환//#include <ctype.h>
int ft_isalnum(int c)
- 알파벳 또는 숫자인지 검사하는 함수
0
을 반환 //#include <ctype.h>
int ft_isascii(int c)
- ASCII코드 문자(0~127)인지 검사하는 함수
1
을 반환0
을 반환 //#include <ctype.h>
int ft_isprint(int c)
- 출력할 수 있는 문자(아스키코드 32~126)인지 검사하는 함수
0
을 반환//#include <ctype.h>
int ft_toupper(int c)
- 소문자를 대문자로 변환하는 함수 (아스키코드 a=97, A=65)
//#include <ctype.h>
int ft_tolower(int c)
- 대문자를 소문자로 변환하는 함수 (아스키코드 a=97, A=65)
//#include <stdlib.h>
int ft_atoi(const char *str)
- 정수형 문자열(char 타입)을 정수(int 타입)로 변환하는 함수
(ex - “ \t - 123abc”)- atof(float) / atoi(int) / atol(long) / atoll(long long) 존재
0
환atoi()
함수의 man 설명에 의하면 오류 처리를 따로 하지 않는다고 함atoi()
함수의 man 설명에 의하면 오류 처리를 따로 하지 않는다고 함long long
최대값, 최소값 오버/언더플로우 예외처리atoi()
함수는 libc에 의해 stdtol()
를 내부에서 돌려 long 타입의 결과값을 리턴한다.Long
: 어느 플랫폼에서든 4 Byte (32비트, 64비트 등의 어느 플랫폼에서든)Int
: CPU의 레지스터와 동일한 크기를 가지는 타입으로 레지스터가 32비트이면 32비트(4 Byte), 64비트면 64비트(8 Byte)가 된다.//#include <stdlib.h>
void *ft_calloc(size_t count, size_t size)
- 크기와 개수에 따라 메모리를 할당하고
0
으로 초기화하는 함수
count
: 할당할 메모리의 개수(길이)size
: 메모리 하나의 크기NULL
반환calloc()
= malloc() + memset()
overflow
여부 확인 가능
?calloc()
함수 내에서 char *
를 만들어 메모리 할당 후 0
으로 세팅하여 void *
로 반환한다면 다른 타입으로 쓸 수 있는가?
void 포인터
//#include <string.h>
char *ft_strdup(const char *s1)
- 주어진 문자열을 새로운 메모리에 메모리를 할당하여 복사 후 반환하는 함수
NULL
반환메모리를 할당하여 메모리 사용이 끝나면 반드시 free
를 사용하여 메모리를 해제해야 한다.
//#include <strings.h>
void ft_bzero(void *s, size_t n)
- 시작점(
s
)에서 주어진 바이트(n
) 만큼 0으로 초기화하는 함수
없음
//#include <string.h>
void *ft_memset(void *b, int c, size_t len);
- 시작점(
b
)에서 주어진 바이트(len
) 만큼 (c
)로 초기화 하는 함수
b
: 메모리 시작 주소c
: 메모르에 초기화시키는 값len
: 초기화할 바이트 수c
의 타입이 int
이지만 내부에서 unsigned char
로 변환해서 처리b
반환 memset()
이 문자c
를 채울 때는 char
단위(1Byte)로 채운다.
바이트 단위로 초기화 하기 때문에 int형 배열을 초기화 할 때 주의해야 한다. (ing형은 4바이트 이므로 4번처리가 된다.
unsigned char
를 쓰는 이유
unsigned char
는 모든 bit를 투명하게 볼 수 있다. (부호비트를 사용하는 비트가 없기 때문)
임의의 메모리에 바이트 단위로 접근해 값을 다룰 때, 반드시 unsigned char
로 접근하도록 요구하고 있다.
//#include <string.h>
void *ft_memcpy*ft_memcpy(void *dst, const void *src, size_t n)
dst
가 가리키는 메모리부터 주어진 바이트(n
) 만큼src
을 복사하는 함수
dst
: 복사될 문자열의 시작 주소src
: 복사할 데이터들의 주소n
: 복사할 데이터의 바이트 수\0
에서 멈추지 않고, 주어진 바이트만큼을 복사함\0
'의 길이도 계산 해야 한다. (문자열 길이 + 1)dst
반환사용시 dst
와 src
의 메모리 영역이 오버랩이 발생 할 수 있을때memmove()
함수를 사용
//#include <string.h>
void *ft_memccpy(void *restrict dst, const void *restrict src, int c, size_t n)
dst
가 가리키는 메모리부터 주어진 바이트(n
) 만큼src
을 복사하는데 문자c
을 찾으면c
다음 주소 값을 반환, 찾지 못하면NULL
값 반환하는 함수
dst
: 복사될 문자열의 시작 주소src
: 복사할 데이터들의 주소c
: 중단할 데이터 n
: 복사할 데이터의 바이트 수n
바이트 이전까지 c
을 찾으면 그다음 주소값을 반환NULL
반환memcpy()
와 똑같이 dst
와 src
의 메모리 영역이 오버랩이 발생 할 수 있음//#include <string.h>
void *ft_memmove(void *dst, const void *src, size_t len);
memcpy()
처럼dst
가 가리키는 메모리부터 주어진 바이트(len
) 만큼src
을 복사하는 함수- 단, 오버랩 예외 처리함
dst
: 복사가 될 곳의 시작 주소src
: 복사할 데이터들의 주소len
: 복사할 데이터의 바이트 수memmove()
는 memcpy()
와 달리 메모리가 겹치는 상태에서의 불상사를 피할 수 있다.memcpy()
와의 차이점은 복사를 할 때 메모리 오버랩 예외 처리를 하냐 안 하냐의 차이, mommove()
는 오버랩 예외 처리함dst < src
인 경우dst > src
인 경우dst
반환//#include <string.h>
void *ft_memchr(const void *s, int c, size_t n)
- : 주어진 바이트(
n
)까지c
문자를 찾으면 해당 주소를 반환, 아닐 시NULL
반환하는 함수
s
: 검색을 할 문자열 주소c
: 찾을 문자n
: 검색할 데이터의 바이트 수일치하는 값이 있으면 그 주소값을 반환
찾지 못했다면 NULL
반환
//#include <string.h>
int ft_memcmp(const void *s1, const void *s2, size_t n)
- : 주어진 바이트까지 두 메모리 블록의 내용이 같은지 비교하는 함수
s1
: 비교할 문자열_1 s2
: 비교할 문자열_2n
: 검색할 데이터의 바이트 수0
을 반환 (s1 - s2)
값을 반환unsigned char
로 형변환strcmp
와 비교하면 strcmp
는 널값까지 비교를 하지만, memcmp
는 중간에 널값이 있어도 주어진 바이트까지 검사한다.//#include <string.h>
int ft_strlen(const char *s)
- 문자열 길이를 구하여 반환
문자열 s
의 길이를 반환
//#include <string.h>
char *ft_strchr(const char *s, int c)
- 주어진 문자를 찾아 주소값 반환, 없으면 NULL 반환
const char *s
: 주어진 문자를 찾을 문자열 주소
int c
: 검색할 문자 ('\0'
도 포함)
NULL
반환'\0'
값이 들어있는 주소를 가리키는 char *를 말한다. c
값이 '\0'
값이면 문자열 s
의 '\0'
값이 들어있는 주소값을 반환하는 조건도 처리해야 한다. //#include <string.h>
char *ft_strrchr(const char *s, int c)
- 주어진 문자를 찾는데 마지막으로 찾은 문자의 주소값 반환, 없으면 NULL 반환
const char *s
: 주어진 문자를 찾을 문자열 주소
int c
: 검색할 문자 ('\0'
도 포함)
NULL
반환return (NULL) 과 return ("")은 다르다
'\0'
값이 들어있는 주소를 가리키는 char *를 말한다. c
값이 '\0'
값이면 문자열 s
의 '\0'
값이 들어있는 주소값을 반환하는 조건도 처리해야 한다. s == 0;
과 s[0] = '\0';
의 차이.
char * s = "" <- 이건 빈문자열
char *s = NULL <- 이건 그냥 s포인터가 가르키는게 없는 것(NULL 인거)
//#include <string.h>
char *ft_strnstr(const char *haystack, const char *needle, size_t len)
- 문자열1
haystack
에서 주어진 길이len
만큼 문자열2needle
이 있는지 확인, 있으면 그 주소값, 없으면 0반환
const char *haystack
: 주어진 문자열s2
를 찾을 문자열 주소
const char *needle
: 찾을 문자열의 시작 주소
size_t len
: 검색할 데이터의 바이트 수
needle
가 없으면 haystack
주소 반환needle
를 찾으면 haystack
에서 찾은 주소 반환NULL
반환const char *
으로 작업 후 char *
형으로 형변환 후 반환해야 한다.//#include <string.h>
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize)
str
을dst
에 <size - 1(널값)> 만큼 복사 후str
총 길이를 반환
char *dst
: 복사될 문자열 시작 주소
const char *src
: 복사할 문자열의 시작 주소
size_t dstsize
: 복사할 데이터의 바이트 수
src
길이를 반환dst
나 src
가 NULL 인 경우, 0
을 반환함.strlcat
, strlcpy
함수는 보안 목적을 위해 만들어진 함수임. 실수하지 않도록 안전하고 오류발생률을 낮춰 철저히 디자인 되었음.strncpy
에서는 src
의 길이가 dst
의 길이와 같거나 더 길 경우, 끝에 NULL 이 들어가지 않음. 하지만 strlcpy
에서는 마지막에 반드시 NULL 종료가 되도록 보증함.
//#include <string.h>
size_t ft_strlcat(char *dst, const char *src, size_t dstsize)
str
을dest
에 <size -1(널값)> 만큼 붙인다(복사한다).
dst
: 복사될 문자열 시작 주소src
: 복사할 문자열 시작 주소dstsize
: 복사할 데이터 바이트 수dst
> dstsize
: src길이
+ dstsize
반환dst
< dstsize
: src길이
+ dst
반환strlcat()
함수는 dst
, src
가 NULL인 경우 에러가 발생한다. 실제 lib 함수도 동일하게 에러가 발생한다.//#include <string.h>
int ft_strncmp(const char *s1, const char *s2, size_t n)
- : 두 문자열을 주어진 길이만큼 같은지 비교
const char s1 : 비교할 문자열1 시작 주소
const char s2 : 비교할 문자열2 시작 주소
size_t n : 비교할 데이터의 바이트 수
0
반환(dest - str)
값을 반환strncmp()
는 s1
과 s2
가 모두 NULL값이 나오면 남은 카운트에 관계없이 0을 반환한다.memcpy()
두 문자열 중 하나가 널값으로 인해 끝나더라도 주어진 바이트가지 비교한다.
size_t 는 unsigned int 이며, 문자열이나 메모리의 사이즈를 나타낼 때 사용합니다. "unsigned int"를 typedef unsigned int size_t;
이렇게 size_t 라는 이름으로 정의해 놓은 것입니다.
size_t
는, 32비트 운영체제에서는 "부호없는 32비트 정수"이고, 64비트 운영체제에서는 "부호없는 64비트 정수"입니다.
그러나 "unsigned int"
또는 "int"는, 64비트 OS라고 해서 꼭 64비트 정수는 아닙니다. 여전히 32비트일 수도 있습니다. 이것이 size_t형과 "unsigned int"형의 차이입니다.
메모리
나 문자열
등의 길이를 구할 때에는 "unsigned int" 대신 size_t 라는 형으로 길이가 반환됩니다.