[C언어/C++] 문자열 복사하기 strcpy, strncpy 함수 사용법 & 예제 + 구현

C언어에서 문자열을 복사하고 싶다면 strcpy이나 strncpy함수를 사용하시면 됩니다. 두 함수의 차이는 복사할 문자열의 길이를 설정하느냐만 다를 뿐 기본적으로 문자열을 복사한다는 것은 같습니다.

 

문자열 복사

strcpy() : 대상 문자열 전체를 복사한다. 
strncpy() : 대상 문자열을 일정 길이만큼 복사한다.

 

strcpy, strncpy 함수 형식

char* strcpy(char * dest, const char* src); 
char* strncpy(char* dest, const char* src, size_t num);

dest : 복사를 받을 대상의 시작 주소
src : 복사를 할 원본의 시작 주소
num : 복사를 할 문자의 개수

 

※ size_t는 해당 시스템에서 어떤 객체나 값이 포함할 수 있는 최대 크기의 데이터를 표현하는 타입으로 반드시 unsigned 형으로 나타냅니다.

 

strcpy, strncpy 사용 예제

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> //함수가 선언된 헤더 파일
//#include <cstring> //C++일 경우

int main() {
  
  char s1[10] = "Hello"; // 10크기 char배열에 Hello 할당
  char s2[10];
  char s3[10];

  strcpy(s2, s1); //문자열 복사 s1 -> s2
  strncpy(s3, s1, 3); //문자열 복사 3자리까지 s1 -> s2

  printf("s1 : %s \n", s1); //원본
  printf("s2 : %s \n", s2); //strcpy
  printf("s3 : %s \n", s3); //strncpy
	
  return 0;
}

예제

strcpy(), strncpy함수는 위와 같이 사용하시면 됩니다. 동작원리는 strcpy() 함수는 null byte를 포함하는 src문자열을 dest 버퍼에 복사하는 개념이고 사용 시 유의해야 할 점은 dest source의 메모리는 겹치지 않아야 하고 dest 버퍼는 src문자열을 복사하기에 충분한 사이즈여야 한다는 것입니다. 그렇지 않다면 Overflow가 납니다.

 

strncpy() 함수는 src 문자열을 n byte만큼 복사하는 것을 제외하면 strcpy() 함수와 같습니다. strncpy() 함수의 경우 str의 문자열 크기가 n byte보다 작다면  dest 함수의 마지막에 추가로 n byte 만큼 null byte로 모두 초기화합니다.

 

strcpy, strncpy 함수 구현

#include <stdio.h>
#include <string.h>

//strcnp 구현
char *my_strcpy(char *dest, const char *src)
{
  char *ret = dest;
  while((*dest++ = *src++)!=0){}

  return ret;
}

//strncpy 구현
char *my_strncpy(char *dest, const char *src, size_t n)
{
  char *ret = dest;

  for(int i=0; i<n; i++)
  {
    if((*dest++ = *src++) == 0){
      while(++i < n){
        *dest++ = 0;
      }
      return ret;
    }
  }
  return ret;
}

int main(int argc, char **argv)
{
  char str1[20] = "Hello";
  char str2[20];

  memset(str2, 0x00, 20);
  my_strcpy(str2, str1); //문자열 복사 str1 -> str2

  printf("%s\n", str2);

  for(int i=1; i<=strlen(str1); i++){
      memset(str2, 0x00, 20);
      my_strncpy(str2, str1, i); //문자열 원하는 길이만큼 복사 str1 -> str2
      printf("%s\n", str2);
  }

    return 0;
}

예제2

 

strcpy_s() 함수 의 추가

char *strcpy_s(char *dest,  size_t count, const char *src);

추가로 위와 같은 오버플로우 문제를 방지하려면 ISO/IEC TR 24731에서 제안된 strcpy_s 함수를 이용하면 됩니다. 이 함수는 마이크로소프트 C 런타임 라이브러리와 일부 C 라이브러리에서 사용이 가능합니다. strcpy, strncpy의 반환 값은destination가 그대로 반환되지만 strcpy_s, strncpy_s 함수의 경우 반환 값이 복사의 성공 여부 또는 복사가 중도 중단된 사유 코드 등이 반환됩니다.

 

strcpy_s() 함수가 추가된 이유

strcpy()는 dest의 유효 공간을 알지 못합니다. 즉 dest로 다른 주소를 부여하더라도 src를 복사해버린다는 뜻으로 아무 공간이나 침범할 가능성을 항상 가지고 있습니다. 안정성 검사를 추가하면 쉽게 해결할 수 있지만 C/C++ 은 기본적으로 데이터의 안정성 검사를 하지 않도록 되어 있습니다. 그리하여 C++은 좀 더 안전성을 추가하기 위해 strcpy_s()라는 함수를 추가로 만들었습니다. strcpy_s() 함수는 dest의 공간 크기를 추가로 받습니다. 물론 데이터의 안정성 검사는 하지 않지만 안전장치만 하나 추가하여 엉뚱한 공간을 침범할 가능성을 낮추어줍니다.

댓글

Designed by JB FACTORY