본문 바로가기
코드리뷰/C언어 리뷰

실전 C언어 코딩 리뷰 - 문자열 복사하기[strcpy() vs strncpy()]

by 디마드 2020. 10. 1.

자바나 C#계열 언어는 String 자료형이 있어서, 문자 A를 B에 복사한다면 "B = A" 이런 식으로 대입을 한다. 반면 C언어는 String 타입이란 게 없어서 이렇게 대입할 경우 원하는 결과가 나오지 않는다. C언어를 어렵게 생각하게 만드는 부분이기도 하다. 문자열 복사는 strcpy()나 strncpy() 함수를 이용한다. 

strcpy() 헤더 파일 : string.h

#include <string.h> 

// src, dest 문자열을 복사하고 문자열(dest)의 시작주소를 리턴한다.
char* strcpy(char* dest, const char* src);

두 번째 인자로 전달받은 메모리 주소에 저장된 문자열을 첫 번째 인자로 전달받은 메모리 주소에 복사한다. 순서가 뒤에서 앞으로이다. 

실전 예제 : strcpy()

[샘플코드]

#include <stdio.h>
#include <string.h>           // strcpy 함수가 선언된 헤더 파일

int main()
{
    char s1[12+1] = "Hello World!";    // 크기가 12인 char형 배열을 선언하고 문자열 할당
    char s2[12+1];                     // 크기가 12인 char형 배열을 선언

    strcpy(s2, s1);          // s1의 문자열을 s2로 복사
    
    printf("%s\n", s2);      // Hello

    return 0;
}

s1, s2 배열 크기에 주목해야 한다. "Hello World!"는 12글자이지만 C언어는 마지막 Null문자를 포함해서 문자열로 인식한다. 따라서 한 문자를 더 포함한 "12+1" 크기로 배열을 만들어야 에러가 발생하지 않는다. 

[실행결과]

Hello World!

 

 

 

 

 

strncpy() 헤더 파일 : string.h

#include <string.h> 

// 지정된 길이(n)만큼 src, dest 문자열 복사하고 문자열(dest)의 시작주소를 리턴한다.
char* strcpy(char* dest, const char* src, size_t n);

세 번째 인자에 복사할 문자 길이가 추가되었다.

실전 예제 : strncpy()

[샘플 코드]

#include <stdio.h>
#include <string.h>           // strcpy 함수가 선언된 헤더 파일

int main()
{
    char s1[12+1] = "Hello World!";    // 크기가 12인 char형 배열을 선언하고 문자열 할당
    char s2[12+1];                     // 크기가 12인 char형 배열을 선언
        
    strncpy(s2, s1, strlen(s1) + 1);          // s1의 문자열을 지정된 길이만큼 s2로 복사
    
    printf("%s\n", s2);      // Hello

    return 0;
}

그런데 왜 strncpy 세 번째 인자에 +1을 했을까? 그 이유는 strlen()이 종료 문자가 포함되지 않는 문자열의 개수를 반환하기 때문이다.  

[실행결과]

Hello World!

만약 "Hello"만 복사하고 싶다면 종료 문자를 직접 입력해야 한다. C언어는 종료 처리를 하지 않아도 컴파일이 정상적으로 된다. 단, 런타임에 종료 문자를 만나지 못해 엉뚱한 메모리를 침범해 쓰레기 값이 함께 출력된다.

실전에서 종종 발생하는 데 정말 디버깅이 어렵다. 소스를 정독하거나 일일이 로그를 찍어 깨진 부분을 찾아야 겨우 찾을 수 있다. C언어가 어렵고 개발 시간이 많이 소요되는 이유이기도 하다.

좋게 말하면 개발자에게 메모리 관리권을 부여했다고 볼 수 있지만, 개발자의 능력에 따라 품질의 차이가 발생하여 관리의 문제가 되기도 한다. 

#include <stdio.h>
#include <string.h>           // strcpy 함수가 선언된 헤더 파일

int main()
{
    char s1[12+1] = "Hello World!";    // 크기가 12인 char형 배열을 선언하고 문자열 할당
    char s2[12+1];                     // 크기가 12인 char형 배열을 선언
        
    strncpy(s2, s1, 5);          // s1의 문자 5개를 S2로 복사
    s2[5] = '\0';                // 마지막에 종료문자 삽입.
    
    printf("%s\n", s2);      // Hello

    return 0;
}

[실행결과]

Hello

 

 

 

 

 

반응형

댓글