C++ strcpy() 문자열 복사 – char 배열과 포인터 | C++ 자습서 14

C++ strcpy() 문자열 복사

문자열 복사 라이브러리 함수인 strcpy 를 사용해서 char 형 배열에서 포인터로 문자열을 복사해보겠습니다. string 객체를 사용하는 방법과는 다릅니다. C언어의 고전 라이브러리를 사용해보고 원리를 파악해 보겠습니다.

원리를 알면 문자열을 다루는 클래스도 직접 만들 수 있습니다. 물론 C++로 프로그램을 만들면 STL의 string 클래스를 활용하는게 최선의 선택입니다.

문자열 처리는 유니코드의 처리도 개발해야 하므로 꽤나 복잡한 기술입니다. 그냥 응용 프로그래머가 심심풀이로 자신만의 라이브러리를 만들기에는 좀 방대한 일 입니다.

다만 자연어 처리나 정규식의 연구에 관심이 있는 분들이라면 C++로 자신만의 문자열 클래스를 만들어 보는 것도 도움이 될 것 입니다. 보통의 앱개발을 하는 분들에게는 불필요하겠죠. 암튼 한글처리는 또 다른 주제니까 여기서는 strcpy 에 대하여 알아보겠습니다.

문자열 복사 예제

아래 예제는 비주얼 스튜디오의 strcpy 예제입니다.

다른 컴파일러에서는 안그럴텐데 비주얼 스튜디오에서는 C4996 경고가 발생할 수 있습니다.

맨위에 #define _CRT_SECURE_NO_WARNINGS 을 추가하고 프로젝트 속성에서

  • 구성속성 – C/C++ – 전처리기 – 전처리기 정의에 ; _CRT_SECURE_NO_WARNINGS 를 추가하면 경고가 사라집니다. 경고가 있으면 컴파일이 진행이 안되기 때문에 비주얼 스튜디오를 쓰는 경우 설정해줍니다.

strcpy는 비어있는 배열에 문자열을 복사하는 함수입니다. 함수는 strcpy(빈 배열, 문자열 들어있는 배열) 의 형태로 char 형 배열의 요소를 처음부터 끝까지 하나씩 가져와서 복사한다는 것을 알 수 있습니다. 그게 첫번째 예제이고 그아래 char pointer 가 문자열에서 포인터로 복사하는 예제입니다.

#include <iostream>
#define _CRT_SECURE_NO_WARNINGS

using namespace std;

int main()
{
    char myOriginal[] = "Hi! This is copy exemple.";
    char myCopied[30];

    cout << "[---------- copy char array ----------]" << endl;

    cout << "- size of string: " << sizeof myOriginal << endl;

    // visual studio 에서는 기본 경고 메시지가 나온다. C4996 오류 해결 구글링
    strcpy(myCopied, myOriginal);

    cout << "- origial string: " << myOriginal << endl;
    cout << "- copied  string: " << myCopied << endl;

    cout << "- address original: " << (void*)myOriginal << endl;
    cout << "- address copied  : " << (void*)myCopied << endl;
    
    cout << "[---------- char pointer(new) ----------]" << endl;

    char* ps;

    // 먼저 동적 할당을 해야한다. strlen + 1 은 '\0' End of String
    ps = new char[strlen(myOriginal)+1];

    strcpy(ps, myOriginal);

    cout << "- copied one: " <<  ps << endl;
    cout << "- copied address(heap) : " <<  (void*) ps << endl;
    cout << "- copied address(stack): " <<  &ps << endl;

    delete[] ps;

    return 0;

}
[---------- copy char array ----------]
- size of string: 26
- origial string: Hi! This is copy exemple.
- copied  string: Hi! This is copy exemple.
- address original: 004FFDB8
- address copied  : 004FFD90
[---------- char pointer(new) ----------]
- copied one: Hi! This is copy exemple.
- copied address(heap) : 00580BF0
- copied address(stack): 004FFD84

위에서 보면 new 키워드로 동적 메모리 할당을 하고 있습니다. 포인터는 변수일 뿐입니다. 새로운 공간에 별도의 문자열을 복사하려면 메모리 공간을 할당받아야 합니다. 즉 새로운 공간을 동적으로 할당 받고 그 공간의 첫번째 주소를 포인터에 대입하는 것입니다.

결과를 보면 문자열이 제대로 출력됨을 알 수 있습니다. 여기서 역참조값이 저장된 메모리를 확인하려면 (void*) 처럼 형변환을 해주면 됩니다. 이건 cout 의 작동 방식때문에 바꿔줘야 하는 겁니다. 위에 heap은 동적 할당을 받은 힙메모리이고 stack 이라 써있는 주소는 그 포인터가 있는 주소입니다.

헷갈리죠? 포인터는 자신이 있는 메모리의 주소와 역참조하는 곳의 주소 두개의 주소를 가지고 있습니다. 요런 차이를 확실히 알고 있어야 나중에 포인터를 참조하고 다시 그 포인터를 참조한다고 할 때 무슨말인지 알아듣습니다.

그리고 자세히 보면 스택 메모리의 주소와 힙 메모리의 주소가 묘하게 떨어져 있는 것을 볼 수 있습니다. 힙 메모리는 동적으로 사용하기 때문에 떨어져 있는 것입니다. 스택은 데이터 구조상 거의 붙어있습니다. C++ 애플리케이션이 메모리를 사용하는 방식은 변수의 범위(scope)에서 다루는 주제입니다.

요약

아래 관련 참고 문서들을 더 읽어 보고 실행해 보면 좋습니다.

참고문서

strcpy – C++ Reference (cplusplus.com)

C++ strcpy() – C++ Standard Library (programiz.com)

strcpy() in C/C++ (tutorialspoint.com)

C++ Strings: strcpy(), strcat(), strlen(), strcmp() EXAMPLES (guru99.com)

참고영상

How Strings Work in C++ (and how to use them) – YouTube

C String Library and String Copy Function – strcpy() – YouTube

Leave a Comment