string.h 헤더 파일에 선언되어 있는 문자열 관련 함수들 중에서 사용 빈도가 높은 함수들을 소개한다.
21장 내용 정리2
문자열의 길이를 반환하는 strlen 함수
strlen 함수는 인자로 전달된 문자열의 길이를 반환해주는 함수이다.
- 인자로 문자열의 포인터를 전달받는다.
- 전달된 포인터가 가리키는 문자열의 길이를 계산하여 반환해 주되, 문자열의 마지막에 추가되는 NULL 문자는 문자열 길이에 포함되지 않는다.
- 리턴타입(반환형) size_t는 그냥 'unsigned int'로 생각하면 된다.
1 2 3 4 | #include <string.h> size_t strlen(const char* s) // 전달되는 문자열의 길이를 리턴 | cs |
예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> #include <string.h> void RemoveBSN(char str[]) { int len = strlen(str); str[len - 1] = 0; // 마지막에 입력받은 \n을 0으로 없애기 } int main(void) { char str[100]; printf("문자열 입력 : "); fgets(str, sizeof(str), stdin); printf("문자열 길이 : %d, 내용 : %s \n", strlen(str), str); RemoveBSN(str); printf("문자열 길이 : %d, 내용 : %s \n", strlen(str), str); return 0; } | cs |
출력결과
출력 결과를 보면 실제 문자열의 길이보다 하나 더 큰 값이 출력되고 있는 것을 확인할 수 있다.
이는 문자열을 입력하고 나서 입력 스트림으로 전송해 주기 위해 누른 Enter 키까지 포함되었기 때문이다.
즉 실행 결과에서 입력한 문자열은 "1234"가 아니라 "1234\n"인 것이다.
RemoveBSN() 함수를 이용하여 \n 을 지워주면 제대로 출력!
문자열을 복사하는 strcpy와 strncpy 함수
strcpy 함수는 문자열을 복사하는 경우에 사용된다.
- 이 함수는 dest로 전달된 배열에 src로 전달된 문자열을 복사한다.
- dest 버퍼가 src의 문자열 길이보다 작으면 어떻게 될까? 배열의 Overflow가 발생한다.
1 2 3 4 | #include <string.h> char* strcpy(char* dest, const char* src); // 리턴 시 복사된 문자열의 포인터 리턴 | cs |
strncpy 함수도 strcpy 함수와 기능은 같다.
- src로 전달된 문자열을 dest로 전달된 배열에 복사를 한다.
- 단! 복사하는 문자열의 최대 길이는 n을 넘지 않는다.
- n 값은 "sizeof(dest)-1" dest의 배열 크기보다 하나 작은 값을 반환하도록 한다.
- "dest[sizeof(dest)-1] = 0" dest의 배열 크기보다 하나 작은 수를 전달하는 이유는 null문자를 삽입해 주기 위해서다.
1 2 3 4 | #include <string.h> char* strncpy(char* dest, const char* src, size_t n); // 리턴 시 복사된 문자열의 포인터 리턴 | cs |
예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <stdio.h> #include <string.h> int main(void) { char str1[20] = "123456789"; char str2[20]; char str3[5]; /* case 1 */ strcpy(str2, str1); puts(str2); /* case 2 */ strncpy(str3, str1, sizeof(str3)); puts(str3); /* case 3 */ strncpy(str3, str1, sizeof(str3)-1); str3[sizeof(str3) - 1] = 0; // null문자 삽입 puts(str3); return 0; } | cs |
출력 결과
문자열을 덧붙이는 strcat과 strncat 함수
strcat 함수
기존에 존재하는 문자열의 뒤에다가 다른 문자열을 추가하는 함수다.
이 함수 역시 경우에 따라 문제를 일으킨다. 문자열을 추가할 배열의 공간이 충분하지 못한 경우 배열 Overflow가 발생한다.
1 2 3 4 | #include <string.h> char* strcat(char* dest, const char* src); // 리턴 시 추가된 문자열의 포인터 리턴 | cs |
strcat 함수의 동작 원리
덧붙임이 시작되는 곳은 null 문자 다음이 아닌 null 문자가 지정된 위치부터다.
strncat 함수
strcat 함수와 기능상으로는 동일하다. 단 strncat 함수는 복사 하고자 하는 문자열의 최대 길이를 인자로 전달하는 기능을 더불어 지니고 있다.
1 2 3 4 | #include <string.h> char* strncat(char* dest, const char* src, size_t n); // 리턴 시 추가된 자열의 포인터 리턴 | cs |
예제
puts 함수가 호출되면 문자열 출력 후 자동으로 개행이 이뤄지지만,
fputs 함수가 호출되면 문자열 출력 후 자동으로 개행이 이뤄지지 않는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h> #include <string.h> char* str2 = "Hello Everybody!"; int main(void) { char str1[20]; int i; int len = strlen(str2); for (i = 0; i <= len; i++) { strcpy(str1, ""); // Null 문자 복사 strncat(str1, str2, i); puts(str1); } return 0; } | cs |
출력 결과
문자열을 비교하는 strcmp 그리고 strncmp 함수
문자열의 내용 자체를 비교하는 함수다. 두 문자열이 같은지 다른지, 다르다면 어떻게 다른지를 알 수 있다.
다음 예제는 흔히 초보 C 프로그래머가 자주하는 실수 중 하나이다.
str1과 str2가 같다는 문자열을 출력하지 않는다. 왜냐하면, 문자열의 내용을 비교한 것이 아니라 str1과 str2(배열 이름도 포인터)라는 포인터를 비교했기 때문이다. str1과 str2는 서로 다른 문자열을 가리킨다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <stdio.h> #include <string.h> char* str1 = "Hello!"; // 문자열 길이 7 int main(void) { char str2[7]; strcpy(str2, str1); // 문자열 복사 printf("str1 : %s \n", str1); printf("str2 : %s \n", str2); if (str1 == str2) // 포인터 비교 printf("str1과 str2는 같습니다. \n"); return 0; } | cs |
strcmp 함수
1 2 3 4 | #include <string.h> int strcmp(const char* s1, const char* s2); // s1과 s2의 비교 결과를 리턴 | cs |
인자로 전달된 포인터 s1과 s2를 비교하여 다음과 같이 결과를 반환해 준다.
문자열이 상대적으로 더 크다는 것은 아스키 코드 값을 비교한 결과를 의미하는 것이다.
"ABC"라는 첫 번째 문자열과 "BCD"라는 두 번째 문자열이 있다. 일단 두 문자열의 첫 번째 문자(A와 B)를 비교한다. 아스키 코드 값이 B가 더 크기 때문에 두 번째 문자열이 더 크다.
실제 프로그램에서 strcmp 함수는 두 문자열이 같은 내용을 지니는지 아닌지를 확인하기 위한 용도로 사용되므로, 같으면 0 다른 경우 0 이외의 값을 반환 한다고 기억하고 있으면 충분하다.
strncmp 함수
문자열을 비교하되 비교할 문자의 길이를 전달받아서 두 문자열을 비교하는 함수이다.
s1이 가리키는 문자열과, s2가 가리키는 문자열의 처음부터 n개까지 비교하는 함수이다.
1 2 3 4 | #include <string.h> int strncmp(const char* s1, const char* s2, size_t n); // s1과 s2의 비교 결과를 리턴 | cs |
예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h> #include <string.h> char* str1 = "ABCDEFG"; char* str2 = "ABCdefg"; int main(void) { if (strcmp(str1, str2) == 0) puts("두 문자열은 일치"); else { puts("두 문자열은 불일치"); if (!strncmp(str1, str2, 3)) puts("그러나 앞 세 글자는 동일"); } return 0; } | cs |
문자 및 문자열에 관련된 그밖에 함수들
C 언어 레퍼런스는 "Prentice Hall"에서 출간한 "A Reference Manual"이나 "프리렉"에서 출판된 "C Programming:완벽 가이드"를 추천한다.
문자열을 숫자로 변환하는 함수들
헤더 파일 stdlib.h에 선언되어 있다.
1 2 3 4 5 | #include <stdlib.h> int atoi(char *str); // 문자열을 int형 데이터로 변환 long atol(char *str); // 문자열을 long형 데이터로 변환 double atof(char *str); // 문자열을 double형 데이터로 | cs |
대소문자의 변환을 처리하는 함수들
ctype.h 헤더 파일에는 대문자를 소문자로, 소문자를 대문자로 변환해 주는 두 개의 함수가 존재한다.
1 2 3 4 | #include <ctype.h> int toupper(int c); // 소문자를 대문자로 int tolower(int c); // 대문자를 | cs |
|
'Books > 열혈강의 C 프로그래밍' 카테고리의 다른 글
[열혈C] 07. Part4 Chapter21 문자와 문자열 처리 함수 (0) | 2018.04.27 |
---|---|
[열혈C] 06. Part3 Chapter20 도전! 프로그래밍 THREE (0) | 2018.04.27 |
[열혈C] 05. Part3 Chapter19 함수 포인터와 void 포인터 (0) | 2018.04.26 |
[열혈C] 04. Part3 Chapter18 다차원 배열과 포인터의 관계 (0) | 2018.04.25 |
[열혈C] 03. Part3 Chapter16-17 내용 정리 (다차원 배열 / 포인터의 포인터) (0) | 2018.04.24 |