본문 바로가기

BackEnd/C

문자열 컨트롤 함수들(strlen,strcpy,strncpy,strcat,strncat,strcmp,strncmp)

반응형

1.  strlen : 문자열의 길이 정보 반환


다음은 문자열의 길이를 계산해서 반환하는 기능의 함수이다.



이 함수는 인자로 전달된 주소값을 시작으로, 널 문자를 만날 때까지 문자의 개수를 세어 나가


는 방식으로 문자열의 길이를 계산하는데, 이 때에 널 문자는 문자열의 길이에 포함이 되지 않는


다. 그리고 이렇게 계산된 문자열의 길이 정보는 함수 호출이 완료되면서 반환된다.


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>
 
int main(void)
{
    char str1[]="1234567";
    char str2[]="프로그래밍";
    char str3[]="C Programming";
 
    printf("%s: %d \n",str1, strlen(str1));
    printf("배열 크기: %d \n\n"sizeof(str1));
 
    printf("%s: %d \n",str2, strlen(str2));
    printf("배열 크기: %d \n\n"sizeof(str2));
 
    printf("%s: %d \n",str3, strlen(str3));
    printf("배열 크기: %d \n\n"sizeof(str3));
 
    return 0;
}

cs

1
2
3
4
5
6
7
8
9
12345677
배열 크기: 8
 
프로그래밍: 10
배열 크기: 11
 
C Programming: 13
배열 크기: 14
 
cs


 위 예제를 보면 한글은 한 글자당 2바이트로 표현되고, 길이도 2배임을 알수 있다.


2. strcpy, strncpy : 문자열 복사



위 두 함수 모두, 두 번째 매개변수 src에 전달된 주소의 문자열을, 첫 번째 매개변수 dest에 전달


된 주소의 메모리 공간에 복사한다. 단 strncpy 함수는 복사할 문자열의 길이가(널 문자를 포함


한 문자열의 길이) 세 번째 전달인자의 값보다 클 경우, 세 번째 전달인자의 크기만큼만 복사를 


진행한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h>
int main(void)
{
    char str1[5];
 
    strcpy(str1, "ABC");
   
    printf("str1: %s \n", str1);
 
    str1[0]='C';
    str1[1]='B';
    printf("str1: %s \n", str1);
 
    return 0;
}

cs

1
2
str1: ABC
str1: CBC
cs

위 예제 7행에서 복사 문자열 ABC를 복사했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <string.h>
 
int main(void)
{
    char src[20]="1234567890";
    char dest1[20];
    char dest2[20];
 
    strcpy(dest1, src);
    strncpy(dest2, src, strlen(src));
 
    printf("dest1: %s \n", dest1);
    printf("dest2: %s \n", dest2);
 
    return 0;
}

cs


1
2
dest1: 1234567890
dest2: 1234567890ftf234567890
cs


위 예제 10행에서는 strcpy 함수의 사용 예를 보여준다. 여기서는 복사될 메모리 공간 dest1이 넉


넉하므로 문제없이 복사가 이뤄진다. 그러나 11행은 문제가 있다. strlen(src)의 반환 값이 10이므


로, 이 문장은 다음과 같은 형식으로 호출이 되어 문제가 발생한다.


strncpy(dest2, src, 10);


최대 열 개의 문자까지 복사가 되는데, 널 문자는 열 한번째 문자이다. 따라서 널 문자는 복사되지 


는다. 그러므로 dest2에 저장된 문자열은 C언어에서 말하는 문자열이 아닌 셈이다(널 문자가 삽


입되지 않았으므로). 그래서 정상이 아닌 출력결과를 보였는데, 이를 수정하기 위해서는 11행을 다


음과 같이 변경하거나 직접 널 문자를 삽입해야 한다. 


strncpy (dest2, src, strlen(src) +1) ; // 널 문자까지 복사를 위해 +1 


위 예제에서는 strncpy 함수의 주의사항을 보여줬는데, 


다음 예제에서는 strcpy 함수의 주의사항을 보여준다. 


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>
 
int main(void)
{
    char src[20]="1234567890";
    char dest1[5];
    char dest2[5];
 
    strcpy(dest1, src);
    
    strncpy(dest2, src, sizeof(dest2)-1);// 널 문자 공간 위해 -1
    dest2[sizeof(dest2)-1]='\0';// 널 문자 삽입
 
    printf("dest1: %s \n", dest1);
    printf("dest2: %s \n", dest2);
 
    return 0;
}


cs


1
2
3
4
배열 크기: 4
 
dest1: 1234567890
dest2: 1234
cs


10행: 배열 src에 저장된 문자열의 길이는 배열 dest1의 길이보다 길다. 이러한 상황에서 10행의 함

수 호출을 하면 dest1에 할당된 메모리 공간을 넘어서서 복사가 진행된다.


12~13행: 반면 strncpy 함수를 사용하면 배열의 길이만큼만 딱 복사가 이뤄지도록 함수의 호출문장을 구성할 수 있다.


추가적으로 strncpy 함수를 이용하면 strcpy 함수가 할 수 있는 모든 일을 안정적으로 처리할 수 있기 때문에, 일반적으로 strncpy 함수의 사용을 추천한다.


3.  strcat, strncat : 문자열 연결


두 개의 문자열을 연결하고 싶은 경우에 사용할 수 있는 함수들이다. 



이 두 함수는 src로 전달된 문자열을 dest로 전달된 문자열의 뒤에 복사한다. 그리고 strcat 함수와 


strncat 함수의 차이점은 길이의 제한이다.


strncat 함수의 세 번 째 전달인자는 덧붙일 문자열의 최대 길이를 제한한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h>
 
int main(void)
{
    char str1[20]="Your name is ";
    char str2[20];
 
    printf("이름을 입력하세요: ");
    gets(str2);
 
    strcat(str1, str2);
    puts(str1);
 
    return 0;
}
cs


1
2
이름을 입력하세요: Hong
Your name is Hong

cs


6행에 선언된 배열 str1의 길이는 20이다. 따라서 이 배열에는 널 문자를 포함해서 최대 길이가 20


을 넘지 않는 문자열만 저장할 수 있다.그리고 12행에서는 이 배열에 문자열을 덧붙이는데,


덧붙 일 문자열이 “Hong”이라면,메모리 상에서는 다음과 같은 방식으로 덧붙임이 진행된다.



strcat 함수는 문자열을 덧붙여서 새로운 문자열을 구성하니, 첫 번째 문자열에 저장된 널 문자가 


삭제되는 것은 당연하다. 


4.  strcmp, strncmp : 두 문자열이 동일한지 확인



위 함수들은 두 문자열이 동일하면 0을 반환 한다 . 그러나 동일 하지 않고 사전 편찬 순서상 첫 


번째 문자열 s1이 앞서면 0보다 작은 값을,


두 번째 문자열 s2가 앞서면 0보다 큰 값을 반환한다.


그리고 함수 strncmp는 비교하는 문자열의 길이가 세 번째 전달 인자의 값보다 크면, 세 번째 전


달인자의 길이만큼만 부분 비교를 한다. 


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
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <string.h>
 
void LexiCmp(char * str1, char * str2);
void LexiPartialCmp(char * str1, char * str2, int len);
 
int main(void)
{
    char str1[]="It is possible to master C"
    char str2[]="It is impossible to master C"
    char str3[]="It is possible to master C in a month or two"
 
    LexiCmp(str1, str2);
    LexiCmp(str1, str3);
    LexiPartialCmp(str1, str3, 26);
 
    return 0;
}
 
void LexiCmp(char * str1, char * str2)
{
    int ret=strcmp(str1, str2);
 
    if(ret==0)
        puts("두 문자열은 동일합니다.");
    else if(ret<0)
        printf("앞서는 문자열: %s \n", str1);
    else
        printf("앞서는 문자열: %s \n", str2);
}
 
void LexiPartialCmp(char * str1, char * str2, int len)
{
    int ret=strncmp(str1, str2, len);
 
    if(ret==0)
        printf("%d번째 문자까지 두 문자열은 동일합니다.\n", len);
    else if(ret<0)
        printf("앞서는 문자열: %s \n", str1);
    else
        printf("앞서는 문자열: %s \n", str2);
}

cs

1
2
3
앞서는 문자열: It is impossible to master C
앞서는 문자열: It is possible to master C
26번째 문자까지 두 문자열은 동일합니다.
cs


20~30행: strcmp 함수를 이용해서, 입력되는 문자열중 사전편찬 순서가 앞서는 문자열을 출력하도록 정의하였다.


32~42행:  strncmp 함수를 이용해서, 입력되는 문자열을 부분적으로 비교할 수 있도록 정의하였다.





반응형