int isalpha (int c);
매개변수 : C언어에서 아스키 코드에 해당하는 문자들은 숫자로 표현이 되고, 문자를 넣으면 자동으로 아스키 코드에 있는 숫자로 들어가기 때문에 int 타입이긴 하지만 'a', 'A', '1' 등을 집어 넣어도됩니다.즉, 'a' 와 같이 char 타입으로 집어 넣어도 자동으로 int 타입으로 형변환 되어서 들어가게 됩니다. 아스키 코드 표를 참고하면 'a'는 자동으로 숫자 97로 형변환되어 들어가게 됩니다.
반환형 : 매개변수로 들어온 인자가 알파벳이라면 0이 아닌 수를 반환하고 알파벳이 아니라면 0을 반환합니다.
더 정확하게 이야기하면 isalpha 함수는알파벳 대문자 "A-Z"는 1을 반환.알파벳 소문자 'a-z"는 2를 반환.알파벳이 아닌것은 0을 반환합니다.
한번더 이야기 하면 isalpha 함수의 매개변수로아스키 코드표에 'A-Z'에 해당하는 65번~90번의 값이 들어오면 1을 반환아스키 코드표에 'a-z'에 해당하는 97번~122번의 값이 들어오면 2를 반환그 이외의 값이 들어오면 0을 반환하는 함수 입니다.
#include "libft.h"
int ft_isalpha(int c)
{
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
return (1);
return (0);
}
c가 '0'~'9'면 1, 아니면 0
#include "libft.h"
int ft_isdigit(int c)
{
if (c >= '0' && c <= '9')
return (1);
return (0);
}
알파벳이거나 '0'~'9'면 1, 아니면 0
#include "libft.h"
int ft_isalnum(int c)
{
if (ft_isalpha(c) || ft_isdigit(c))
return (1);
return (0);
}
1번 부분 (code 0 ~ 31)
ASCII control characters는 인쇄가 불가능한 제어코드들입니다.
프린터 같은 주변기기들을 제어할 때 사용됩니다.
2번 부분 (code 32 ~ 127)
ASCII printable characters는 다른 어떠한 ASCII 변형 테이블에서도, 공통적으로 사용되는 인쇄 가능한 문자로 불립니다.
문자, 숫자, 구두점 및 기타 기호들을 나타냅니다. 또한 키보드에 있는 거의 모든 문자를 찾으실 수 있습니다.
(127은 DEL 명령을 나타냅니다.)
3번 부분 (code 128 ~ 255)
Extended ASCII characters는 ISO 8859-1dp를 따르며 ISO Latin-1로도 불립니다.
code 128 ~ 159는 Microsoft Windows Latin-1 확장 문자가 포함되어 있습니다.
#include "libft.h"
int ft_isascii(int c)
{
if (c >= 0 && c <= 127)
return (1);
return (0);
}
2번 부분이 출력 가능한 부분
#include "libft.h"
int ft_isprint(int c)
{
if (c >= 32 && c <= 126)
return (1);
return (0);
}
#include"libft.h"
size_t ft_strlen(const char *s)
{
size_t i;
i = 0;
while (s[i])
i++;
return (i);
}
b = string
c = 대입할 문자
len = 얼마만큼 대입할건지
return 값은 b의 주소값
#include"libft.h"
void *ft_memset(void *b, int c, size_t len)
{
unsigned char *res;
size_t i;
res = (unsigned char *)b;
i = 0;
while (i < len)
res[i++] = (unsigned char)c;
return (b);
}
n만큼 0을 채워넣음
#include"libft.h"
void ft_bzero(void *s, size_t n)
{
ft_memset(s, 0, n);
}
첫번째 인자 void * dest= 복사 받을 메모리를 가리키는 포인터
두번째 인자 const void *source= 복사할 메모리를 가리키고 있는 포인터
세번째 인자 size_t num= 복사할 데이터(값)의 길이(바이트 단위)
두번째 인자(source)에 있는 원본을 세번째 인자(num)만큼의 길이 만큼 복사해서첫번째 인자(dest)에 붙여 넣는 함수 입니다.
성공 시 dst, 실패 시 0 return
dst 와 src 중 하나라도 비어있을 시 0을 리턴하도록 했는데 오류남;;;
void *ft_memcpy(void *dst, const void *src, size_t n)
{
size_t i;
unsigned char *in_dst;
unsigned char *in_src;
if (!dst || !src)
return (0);
in_dst = (unsigned char *) dst;
in_src = (unsigned char *) src;
i = 0;
while (i++ < n)
*in_dst++ = *in_src++;
return (dst);
}
void *ft_memcpy(void *dst, const void *src, size_t n)
{
size_t i;
unsigned char *in_dst;
unsigned char *in_src;
if (!dst && !src)
return (0);
in_dst = (unsigned char *) dst;
in_src = (unsigned char *) src;
i = 0;
while (i++ < n)
*in_dst++ = *in_src++;
return (dst);
}
둘 다 비어있을 시 0을 return 해야함
#include"libft.h"
void *ft_memcpy(void *dst, const void *src, size_t n)
{
size_t i;
unsigned char *in_dst;
unsigned char *in_src;
if (!dst && !src)
return (0);
in_dst = (unsigned char *) dst;
in_src = (unsigned char *) src;
i = 0;
while (i++ < n)
*in_dst++ = *in_src++;
return (dst);
}
void memmove (void dest, const void* src, size_t num);
첫번째 인자 void* dest= destination.복사 한걸 붙여넣을 메모리를 가리키는 포인터 입니다. (목적지)
두번째 인자 void* src= source.복사 할 메모리를 가리키는 포인터 입니다. (출발지)
세번째 인자 size_t num= 복사할 바이트 길이 입니다.
반환형= 첫번째 인자인 dest를 반환 합니다.
함수 설명. src가 가리키는 메모리로 부터 num 바이트 사이즈 만큼 dest가 가리키는 메모리에 옮깁니다. move 라서 잘라내고 붙여넣는다고 생각하실수 있지만, 이것도 복사하는 기능을 가진 함수 입니다.그러면 복사 만 하는거면 [memcpy]와 같다고 생각하실 수 있겠지만, memcpy는 바로 그냥 어디 거치지 않고 그 위치에 복사해서 붙여넣는다고 생각하시면 되고, memmove는 그것보다는 안전하게, 복사할것을 버퍼에 복사하고 해당 위치에 가서 버퍼에 복사된 것을 붙여 넣는 식으로 동작이 구현되어있습니다.성능을 "굳이" 따지자면 memcpy가 버퍼를 거치지 않고 복사하기 때문에 좀더 좋긴 하겠지만, 버퍼를 이용하는 memmove가 더 안정성이 좋습니다.
에러 이유
overlapped 하는 경우
dst> src 인 경우를 생각하지 않음
#include"libft.h"
void *ft_memmove(void *dst, const void *src, size_t len)
{
unsigned char *dst2;
unsigned char *src2;
if (dst == src || !len)
return (dst);
dst2 = (unsigned char *)dst;
src2 = (unsigned char *)src;
if (dst < src)
{
while (len--)
*dst2++ = *src2++;
}
else if (dst > src)
{
while (len--)
*(dst2 + len) = *(src2 + len);
}
return (dst);
}
size_t strlcpy(char dst, const char src, size_t dstsize)
strlcpy
는 문자열을 복사해주는 함수인데, dest
안에 src
의 값을 복사해 준다. size
는 src의 길이 이하
일때 이용되는 녀석이다. strlcpy
는 src의 '\0'
값을 만나기 전 혹은 size - 1
만큼 복사가 이루어 졌을때 복사를 중지한다.
dstsize가 0일 경우 처리안함
#include"libft.h"
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize)
{
size_t src_len;
src_len = 0;
while (src[src_len])
src_len++;
if (dstsize == 0)
return (src_len);
while (--dstsize && *src)
*dst++ = *src++;
*dst = '\0';
return (src_len);
}#include"libft.h"
size_t ft_strlcat(char *dst, const char *src, size_t dstsize)
{
unsigned int dst_len;
unsigned int src_len;
unsigned int n;
char *p;
p = dst;
dst_len = ft_strlen(dst);
src_len = ft_strlen(src);
if (dstsize <= dst_len)
return (src_len + dstsize);
n = dstsize - dst_len - 1;
while (*p)
p++;
while (*src != '\0' && n)
{
*p++ = *src++;
n--;
}
*p = '\0';
return (dst_len + src_len);
}#include"libft.h"
size_t ft_strlcat(char *dst, const char *src, size_t dstsize)
{
unsigned int dst_len;
unsigned int src_len;
unsigned int n;
char *p;
p = dst;
dst_len = ft_strlen(dst);
src_len = ft_strlen(src);
if (dstsize <= dst_len)
return (src_len + dstsize);
n = dstsize - dst_len - 1;
while (*p)
p++;
while (*src != '\0' && n)
{
*p++ = *src++;
n--;
}
*p = '\0';
return (dst_len + src_len);
}#include"libft.h"
size_t ft_strlcat(char *dst, const char *src, size_t dstsize)
{
unsigned int dst_len;
unsigned int src_len;
unsigned int n;
char *p;
p = dst;
dst_len = ft_strlen(dst);
src_len = ft_strlen(src);
if (dstsize <= dst_len)
return (src_len + dstsize);
n = dstsize - dst_len - 1;
while (*p)
p++;
while (*src != '\0' && n)
{
*p++ = *src++;
n--;
}
*p = '\0';
return (dst_len + src_len);
}
두 문자열을 붙이는 함수
이다. dest
의 맨 뒤에 src
를 size
만큼만 붙인다. 만약 size가 dest의 길이 이하
라면 문자열을 붙이는 과정이 사라지고 size가 더 크다면
size - 1만큼 src를 붙이고 마지막에 '\0'값을 넣어주고 리턴 값은 dest의 길이 + src의 길이
이다.
#include"libft.h"
size_t ft_strlcat(char *dst, const char *src, size_t dstsize)
{
unsigned int dst_len;
unsigned int src_len;
unsigned int n;
char *p;
p = dst;
dst_len = ft_strlen(dst);
src_len = ft_strlen(src);
if (dstsize <= dst_len)
return (src_len + dstsize);
n = dstsize - dst_len - 1;
while (*p)
p++;
while (*src != '\0' && n)
{
*p++ = *src++;
n--;
}
*p = '\0';
return (dst_len + src_len);
}
길이를 지정하여 두 문자열을 비교하는 함수
일치할 시 0 return
#include"libft.h"
int ft_strncmp(const char *s1, const char *s2, size_t n)
{
while (n > 0 && *s1 != '\0' && *s2 != '\0')
{
if (*s1 != *s2)
break ;
s1++;
s2++;
n--;
}
if (n == 0)
return (0);
return (*(unsigned char *)s1 - *(unsigned char *)s2);
}
ft_toupper : 소문자인 알파벳들을 대문자로 바꿔주는 함수
ft_tolower : 대문자인 알파벳들을 소문자로 바꿔주는 함수
int ft_toupper(int c)
{
if (c >= 'a' && c <= 'z')
c -= 'a' - 'A';
return (c);
}
int ft_tolower(int c)
{
if (c >= 'A' && c <= 'Z')
c += 'a' - 'A';
return (c);
}
문자열 내에 일치하는 문자가 있는지 검사하는 함수
문자열에서 찾은 문자위치의 포인터를 리턴
틀린 이유 - 비교하는 c가 int로 들어오기 때문에 이를 char로 바꿔주고 비교해야함
c를 unsigned char로 바꾸어 비교해줌
→ 자꾸 NULL이 리턴됨 ...
s가 const char여서 주소값을 옮길 시 작동하지 않음 → 따라서 char로 다른 변수를 선언해 준 후 s를 char의 형태로 저장함
→ 그래도 안됨
그냥 i써서 함 ,.
int a = NULL;
char a = NULL = 0;
char a = 0 = '\0'
while (!s) ≠ while (*s ≠ ‘\0’) 의 차이 ?
당연함 헷갈렸었음 ..
#include"libft.h"
char *ft_strchr(const char *s, int c)
{
char *str;
str = (char *)s;
while (*str)
{
if (*str == (char)c)
return ((char *)str);
str++;
}
if ((char)c == *str)
return ((char *)str);
return (NULL);
}
strrchr() 함수는 문자열에서 찾은 문자 위치의 포인터를 리턴
strrchr() 함수는 문자열 s에서 마지막으로 있는 문자 c의 포인터를 리턴합니다.
안이 ... 이것도 헷갈림 while(*s) 이거여야되는데 while(!(**s))로 씀 .. 아 딮빡
#include"libft.h"
char *ft_strrchr(const char *s, int c)
{
char *last;
last = 0;
while (*s)
{
if (*s == (char)c)
last = (char *)s;
s++;
}
return (last);
}
아니 이게 왜 안돼??
는 c 가 ‘\0’인 경우를 안해준듯?
#include"libft.h"
char *ft_strrchr(const char *s, int c)
{
char *last;
last = 0;
while (*s)
{
if (*s == (char)c)
last = (char *)s;
s++;
}
if (*s == (char)c)
last = (char *)s;
return (last);
}
C언어 메모리 관련 함수 memchr()은 메모리 영역에서 임의의 문자를 검색하고 있으면 그 위치의 포인터를 구합니다.
이 함수를 작성하면서 헷갈렸던 점은 void형 포인터 반환일때 &buffer[10] 작성이 불허하다는 것이였다.
그 이유는 &buffer[10]가 &(buffer + 10)를 평가하기 때문입니다. 왜냐하면 배열 첨자 연산자는 연산자 &의 주소보다 우선 순위가 높기 때문이다. 그러나 버퍼 유형이 void 이며 크기 정보가 없기 때문에 void 포인터에서는 포인터 계산을 수행할 수 없습니다. 버퍼에 타입캐스트 연산자(char )를 사용하면 다음과 같이 필요한 크기 정보가 제공됩니다.
(char )buffer + 10은 (char)의 버퍼 + 10 크기 또는 가변 버퍼가 가리키는 버퍼의 11번째 요소의 주소와 동일합니다.
즉, 정리하자면
&buffer[10]
대신에
(char *)buffer + 10
로 작성을 해야한다.
#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 ((void *)s + i);
i++;
}
return ((void *)0);
}
int memcmp(const void s1, const void s2, size_t n)
s1 이 가리키는 처음 n
바이트의 데이터와 s2 가 가리키는 처음 n
바이트의 데이터를 비교하여 이들이 같다면 0 을 리턴하고 다르다면 0 이 아닌 값을 리턴한다. 이 때 리턴되는 값은 아래를 참고.
두 개의 메모리 블록의 관계에 따라 아래와 같이 정수 값을 리턴한다.
ptr1
과 ptr2
가 가리키는 메모리 블록에서 앞에서 부터 처음으로 다른 바이트를 살펴 보는데, 그 바이트를 unsigned char
로 해석하였을 때, 그 값이 ptr1
이 더 크면 0 보다 큰 값을, 아니면 0 보다 작은 값을 리턴한다.틀린 이유
#include"libft.h"
int ft_memcmp(const void *s1, const void *s2, size_t n)
{
unsigned char *cp_s1;
unsigned char *cp_s2;
cp_s1 = (unsigned char *)s1;
cp_s2 = (unsigned char *)s2;
while (n)
{
if (*cp_s1 != *cp_s2)
return (*cp_s1 - *cp_s2);
cp_s1++;
cp_s2++;
n--;
}
return (0);
}
char strnstr(const char big, const char *little, size_t len);
이 함수는 big 문자열에 len 길이 중에서 little 문자열을 찾는 것이다.
반환 값
만약 little 값이 비어 있으면 big를 반환한다.
big 문자열에서 little 문자열을 찾지 못하면 NULL을 반환한다.
little 문자열을 찾으면 big에 little 문자열 시작 부분 위치 주소를 반환한다.
strnstr()
함수는 종료전까지의 문자들 중 big 문자열 내에서 찾은 little
문자열 중 첫번째로 나온 결과를 찾는다. 문자열은 최대 len
의 수까지만 탐색한다.\0
을 만나면 더이상 찾지 않는다while ((str[i] == find[j]) && i < len)
while (str[i] && i + ft_strlen(find) < len)
char *ft_strnstr(const char *str, const char *find, size_t len)
{
size_t i;
size_t j;
if (!find[0])
return ((char *)str);
i = 0;
while (str[i] && i + ft_strlen(find) <= len)
{
if (str[i] == find[0])
{
j = 0;
while (find[j] || str[i + j])
{
if (str[i + j] != find[j])
break ;
else if (j == ft_strlen(find) - 1)
return ((char *)str + i);
j++;
}
}
i++;
}
return (NULL);
}
while 문에서 i + ft_strlen(find) <= len 이 부분에서 등호를 쓰지 않아서 틀린 것이다 ..!!
#include"libft.h"
char *ft_strnstr(const char *str, const char *find, size_t len)
{
size_t i;
size_t j;
if (!find[0])
return ((char *)str);
i = 0;
while (str[i] && i + ft_strlen(find) <= len)
{
if (str[i] == find[0])
{
j = 0;
while (find[j] || str[i + j])
{
if (str[i + j] != find[j])
break ;
else if (j == ft_strlen(find) - 1)
return ((char *)str + i);
j++;
}
}
i++;
}
return (NULL);
}
atoi = char to int = 문자열을 정수 타입으로
atoi 함수는 nptr 로 지정된 문자열을 int 형으로 변환한다. 이때 변환범위는 숫자로 인식가능한 선까지이다.
예를들어 아규먼트로 "1234ab" 가 주어졌다면 숫자로 인식가능한 문자열범위는 "1234" 이므로 1234 로 변환되게 된다.
만약 변환시킬만한 적당한 문자가 존재하지 않는다면 0을 리턴한다.
atoi() 함수는 입력 문자를 숫자로 해석하여 생성되는 int 값을 리턴합니다. 함수가 입력을 해당 유형의 값으로 변환할 수 없는 경우 리턴값은 0입니다. 리턴값은 오버플로의 경우 정의되지 않습니다.
#include"libft.h"
const char *skip_whitespace(const char *str)
{
while (*str == ' ' || (*str >= 9 && *str <= 13))
str++;
return (str);
}
int ft_atoi(const char *str)
{
long n;
long sign;
n = 0;
sign = 1;
str = skip_whitespace(str);
if (*str == '-')
sign = -1;
if ((*str == '-') || (*str == '+'))
str++;
while ((*str != '\0') && ('0' <= *str) && (*str <= '9'))
{
n = (n * 10) + (*str - '0');
if (n > 2147483647 && sign == 1)
return (-1);
if (n > 2147483648 && sign == -1)
return (0);
str++;
}
return (n * sign);
}
malloc은 할당된 공간의 값을은 바꾸지 않는다.
calloc은 할당된 공간의 값을 모두 0으로 바꾼다.
배열을 할당하고 모두 0으로 초기화할 필요가 있을경우에는 calloc을 쓰면 편하다.
#include "libft.h"
void *ft_calloc(size_t count, size_t size)
{
void *ptr;
ptr = malloc(size * count);
if (ptr == 0)
return (0);
ft_memset(ptr, 0, size * count);
return (ptr);
}
char strdup(const char s1)
💻Parameters
s
: 복사할 문자열
💻Return value
string
을 복사한 메모리주소(복사된 문자열의 주소를 가리키는 포인터)
실패 시 NULL
malloc
+ strcpy
#include"libft.h"
char *ft_strdup(const char *s1)
{
size_t i;
char *res;
i = 0;
res = (char *)malloc(sizeof(char) * (ft_strlen(s1) + 1));
if (!res)
return (0);
while (s1[i])
{
res[i] = s1[i];
i++;
}
res[i] = 0;
return (res);
}
SUBSTR 함수는 문자단위로 시작위치와 자를 길이를 지정하여 문자열을 자른다.
#include"libft.h"
char *ft_substr(char const *s, unsigned int start, size_t len)
{
size_t i;
size_t j;
char *res;
i = 0;
j = 0;
if (!s)
return (NULL);
res = (char *)malloc(sizeof(char) * (len + 1));
if (!res)
return (NULL);
while (s[i])
{
if (i >= start && j < len)
{
res[j] = s[i];
j++;
}
i++;
}
res[j] = '\0';
return (res);
}