티스토리 뷰

2021.02.25.목

이 전의 #7일 차 정리에서는 문자열 관련 함수의 사용 예제를 위주로 살펴보았다면 이번에는 함수의 원형, 즉 함수의 선언부를 살펴보려 한다. 아래의 함수는 모두 <string.h> 헤더 파일에 속해 있으므로 반드시 전처리가 필요하다.

 

 

strcpy() 함수

✔ char 배열은 문자열을 저장하는 변수의 역할

✔ 다른 문자열로 바꾸어야 할 때에는 변경하고자 하는 문자열의 문자를 요소마다 다시 저장해야 하는 번거로움이 있다.

✔ 첫 번째 인자로 저장할 공간의 주소(포인터)를 받고, 두번째 인자로는 수정할 문자열을 받는다.

 

char * strcpy(char * dest, const char * src) ;

✔ 첫번째 인자(dest)로 받을 수 있는 값은 char 배열과 배열명을 저장한 포인터만 가능.

✔ 문자열 상수는 값을 바꿀 수 없으므로, 프로그램 실행 시 에러가 발생한다.

✔ 문자열 상수의 주소를 저장한 포인터를 통해 접근하여 값을 수정하는 것은 문법상으로는 가능하나 사용해서는 안된다.

 

✔ 두 번째 인자(src)로 받는 값은 수정한 문자열로, 여러 가지 형태를 받아온다.

✔ 문자열 상수를 직접 입력해도 되는 이유는 문자열 상수의 첫 번째 문자의 위치를 전달하기 때문.

 

 

strncpy() 함수
char * strncpy(char * dest, const char * src, size_t n) ;

✔ 문자열을 복사할 공간(dest)에 문자열(src)을 n 만큼 복사해 저장하는 함수

✔ 문자를 n만큼만 복사해 저장하기 때문에 null을 자동으로 저장하지 않으므로 별도로 저장해야 한다.

✔ strcpy()는 복사할 문자열의 길이가 저장할 공간보다 크다면 버퍼 오버플로우가 발생.

 

 

strcpy()와 strncpy()의 차이점

✔ 이에 대한 대응책이 strncpy()이며, 이는 string new copy의 약자이다.
✔ 그러므로 복사할 문자열의 크기를 지정하여 가져오는, 비교적 방어적인 strncpy()를 사용하는 것을 추천.
✔ 하지만 strncpy() 또한 버퍼 오버플로우에서 완벽히 자유로운 것은 아니므로, 주의가 필요하다.

 

 

strcat() 함수
char* strcat(char* dest, const char* origin);
char str1[10] = "apple"; 
char str2[10] = "jam"; 

printf("%s\n",strcat(str1,str2)); //applejam 
printf("%s\n",str1); //applejam

✔ 함수의 원형은 위와 같으며 매개변수로는 붙여 넣을 문자열 주소(dest)와 이어 붙일 문자열의 주소(origin)를 받는다.

✔ 먼저 붙여 넣을 문자열에서 null 문자의 위치를 찾아 그 이후에 문자열을 복사해 이어 붙이도록 구현되어있다.

✔ 이어 붙인 뒤에는 null문자를 저장하며 마무리한다.

 

✔ 문자열을 덧붙이는 함수이므로, 붙여 넣을 공간이 부족한 경우 다른 메모리 영역을 침범할 수 있으니 주의하자.

✔ strcat() 함수로 붙여 넣기 전에 반드시 붙여 넣을 공간인 배열이 초기화되어있어야 한다.

✔ 배열의 초기화 방법은 아래를 참고하자.

char str[80] = {'\0'}; 		// 명시적으로 널 문자를 초기화
char str[80] = {0}; 		// 널 문자의 아스키 코드 값으로 초기화
char str[80] = ""; 		// 큰따옴표 안에 아무것도 없으므로 널 문자만 초기화
str[0] = '\0'; 			// 첫 번째 배열 요소만 별도로 초기화

 

 

strncat() 함수
char* strcat(char* dest, const char* origin, size_t n) ;
char str1[10] = "apple "; 
char str2[10] = "mango"; 

printf("%s\n",strcat(str1,str2)); 	//apple mango 
printf("%s\n",strncat(str1,str2,1)); 	//apple mangom

✔ 함수의 원형은 위와 같으며, strcat() 함수와 달리  몇 개의 문자를 이어 붙일 지에 대해 n 이라는 매개변수를 추가로 받는다.

✔ 이어붙일 문자의 개수가 정해져 있으므로, 이어 붙인 후에 null문자를 저장해 문자열을 완성한다.

 

 

strlen()함수
size_t strlen(const char* s);
char str1[10] = "apple"; 
char str2[10] = "jam"; 

printf("%lu\n",strlen(str1)); //5 
printf("%lu\n",strlen(str2)); //3

✔ 일반적으로 문자열을 저장하는 char형 배열은 다양한 길이의 문자열을 저장할 수 있도록 충분히 크게 크기를 선언한다.

✔ 실제로 char형 배열에 저장된 문자열의 길이를 알고 싶다면 strlen()함수를 사용하자.

문자열의 끝을 알리는 null문자를 제외한 문자열의 길이를 반환 (공백 포함)

✔ strlen()함수의 원형을 살펴보면 반환 값의 자료형이 size_t라는 것을 알 수 있다.

✔ size_t는 부호 없는 정수형(unsigned integer)이라는 의미.

✔ sizeof, alignof, offsetof의 반환 값이 이에 속하며, 형식 지정자는 %lu를 사용한다.

 

 

strcmp() 함수
 int strcmp(const char *string1, const char *string2);

✔  strcmp() 함수는 두 문자열의 순서를 아스키코드를 기준으로 판단하여 숫자로 결과를 반환한다.

✔  문자열의 첫 번째 문자부터 비교하며, 같은 문자라면 그다음 문자를 차례로 비교하여 판단한다.

char str1[10] = "aaa"; 
char str2[10] = "bbb"; 
char str3[10] = "bbb"; 

printf("%d\n", strcmp(str1, str2));	// aaa와 bbb를 비교했을 때, aaa가 더 빠르므로 -1
printf("%d\n", strcmp(str2, str1));	// bbb와 aaa를 비교했을 때, bbb가 더 빠르므로 1
printf("%d\n", strcmp(str2, str3));	// bbb와 bbb는 동일하므로 0

✔  아스키코드가 첫 번째 인자보다 두 번째 인자가 나중에 나오면 음수를 반환한다. (a=97, b=98)

✔  아스키 코드가 첫번째 인자보다 두번째 인자가 먼저 나오면 양수를 반환한다. 

✔  아스키 코드가 첫번째 인자보다 두번째 인자가 동일하면 0을 반환한다.

char str1[10] = "pear"; 
char str2[10] = "peach"; 

// 1. pear VS peach

printf("%d\n", strcmp(str1, str2));	

// 최초로 다른 문자는 r과 h
// r-h = 81-71 = 10
// 위와 같은 이유로 10 반환


// 2. peach VS pear

printf("%d\n", strcmp(str1, str2));	

// 최초로 다른 문자는 h와 r
// h-r = 71-81 = -10
// 위와 같은 이유로 -10 반환

✔  반환되는 값이 양수인지 음수인지는 사전 순서에 따라 결정되지만 반환되는 값은 어떻게 결정되는 걸까

✔  최초로 동일하지 않은 문자의 아스키코드를 구해 빼주면 어떤 값이 반환되는지 알 수 있다.

 

 

strncmp() 함수
int strcmp(const char *string1, const char *string2);

✔ 함수의 원형은 위와 같으며, strcmp() 함수와 달리 몇 개의 문자를 비교할 지에 대해 n이라는 매개변수를 추가로 받는다.

 

 

연산 함수의 직접 구현 (strcpy함수)
char * strcpy(char * dest, const char * src) ;
char* my_strcpy(char* str1, char* str2){
	char *ch = str1;		
	if(str1[0] == 0) return str1;
	for(int i=0; i<80; i++){
		if(str2[i] == 0) break;
		str1[i]=str2[i];	
	}
	return str1;			
}

✔ 함수의 원형을 살펴보며 strcpy() 함수를 직접 구현해보자.

✔ 매개변수로 복사받을 곳과 복사할 값의 포인터를 전달받는다.

✔ 함수가 종료했을 때, 복사받을 곳의 첫 주소로 초기화된 char형 포인터 변수를 반환한다.

 

✔ 복사할 값이 null이 아니라면 대입하고, 주소 위치를 1씩 증가하며 값을 저장한다. (for문 사용)

✔ 복사할 값이 null문자라면 반복문을 종료하고, 해당 위치에 null문자를 저장한다.

✔ 복사 받을 곳의 첫 주소로 초기화된 char형 포인터 변수를 반환하며 함수를 종료한다.

 

 

 

 

 

[참고] 한빛미디어-혼자 공부하는 C언어 유튜브 강의 / 엘리스 트랙-혼자 공부하는 C언어 / 길벗-C언어 코딩 도장 / 위키백과

 

댓글
«   2025/04   »
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
최근에 올라온 글
글 보관함
Total
Today
Yesterday