본문 바로가기

Books/열혈강의 C 프로그래밍

[열혈C] 08. Part4 Chapter21 문자와 문자열 처리 함수2


표준 C 라이브러리에는 문자열에 관련된 다양한 함수를 제공한다. 
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 언어 레퍼런스(Reference)를 하나 구입하자. 레퍼런스에는 문자열 관련 함수뿐만 아니라, ANSI 표준으로 정의되어 있는 모든 함수에 대한 소개가 들어 있다. 그리고 필요한 함수들을 직접 찾아보는 습관을 들이자. 무작정 함수만을 공부하는 것은 좋은 공부방법이 아니다. (함수만 공부하는 것보다 포인터를 보다 확실히 이해하는 것이 거짓말 조금 보태서 백배 낫다.) 필요한 함수를 참조하는 것도 하나의 실력이다.
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




열혈강의 C 프로그래밍
국내도서
저자 : 윤성우
출판 : 프리렉 2003.12.15
상세보기