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