C++ 문자열(String)
목차
이전 학습에서 C++의 char 배열을 사용한 문자열에 대하여 알아봤습니다. string 문자열은 string 객체를 사용한 문자열입니다. 이 방식이 char 를 사용하는 것 보다 훨씬 스마트하게 문자열을 사용할 수 있습니다.
문자열 정의
아래 예제를 보면 문자열을 손쉽게 정의할 수 있습니다. ” ” 따옴표로 텍스트를 string 객체 타입에 저장하는 방식입니다. 물론 각 문자들 H y u n d a i 들은 모두 고유의 아스키 코드값으로 메모리에 저장될 것 입니다. 아스키 코드는 1바이트 이므로 내부적으로는 char 형 포인터 주소를 사용해서 문자열의 제일 첫번째 요소에 접근합니다.
string 객체를 하나더 선언해서 객체를 대입할 수도 있습니다. 이 때도 메모리 주소를 확인하면 각각 독립된 공간에 문자열을 보관하는 것을 볼 수 있습니다.
string은 연산자 오버라이딩(내용을 바꿔쓰는 것)이 되어 있습니다. + 난 = 연산자들에서 일반적인 숫자형 변수에 적용되는 것과 다른 결과를 볼 수 있습니다. 편하게 사용할 수 있도록 미리 객체의 연산자를 오버라이딩 한 결과 입니다. 프로그래밍에서 연산자가 나왔을 때 모두 같다고 생각하면 안됩니다.
내부적으로 데이터를 처리하는 방법에 차이가 있을 수 있으니까요.
#include <iostream> #include <string> using namespace std; int main() { string myStr = "Hyundai Auto"; cout << " myStr : " << myStr << endl; // 객체를 대입한다 string newStr = myStr; cout << "newStr : " << newStr << endl; cout << "- address myStr : " << &myStr << endl; cout << "- address newStr : " << &newStr << endl; // string 연산 cout << "--> " + newStr + " Company"; return 0; }
myStr : Hyundai Auto newStr : Hyundai Auto - address myStr : 0x61fec4 - address newStr : 0x61feac --> Hyundai Auto Company
char 배열과 string 객체
char 배열 문자열과 string 객체 문자열은 문자열이라는 공통점이 있지만 여러 차이도 있는데요. 몇가지 차이점을 코드로 비교해봤습니다.
#include <iostream> #include <cstring> using namespace std; int main() { // char 의 사용 cout << "[---------- char 문자열 ----------]" << endl; char myCh1[] = "my string"; char myCh2[20]; cout << "* - 글자 개수: " << strlen(myCh1) << endl; cout << "* - 사이즈: " << sizeof myCh1 << endl; // 문자열 복사하기 strcpy(myCh2, myCh1); cout << "* - 원본 : " << myCh1 << endl; cout << "* - 사본 : " << myCh2 << endl; cout << "* - 합친 것 : " << strcat(myCh1, " [plus something]") << endl; // char 배열의 경우 아래와 같은 할당은 안된다 // myCh1 = "test"; char myCh3[15] = "char array"; cout << "* - 글자수 myCh1 : " << strlen(myCh3) << endl; cout << "* - Byte myCh1 : " << sizeof myCh3 << endl; // string 객체의 사용 cout << endl << "[---------- string 객체 ----------]" << endl; string myStr1 = "Smoothie Coding"; string myStr2; // 단순 출력 cout << "@ - string 객체 myStr1 : " << myStr1 << endl; myStr1 += " -> upgrade your code"; cout << "@ - string 객체 myStr1 : " << myStr1 << endl; // string 객체 대입 myStr2 = myStr1; cout << "@ - string 객체 myStr2 : " << myStr2 << endl; cout << "@ - 주소 myStr1 : " << &myStr1 << ", @ - 주소 myStr2 : " << &myStr2 << endl; // string 은 const char* 전용 함수들과 호환하지 않는다. // cout << strlen(myStr1); // cout << strcpy(myStr1, myStr2); // strcat(myStr1, " plus something"); // 문자열 재할당 myStr1 = "Hello"; cout << "@ - 글자수 myStr1 : " << myStr1.size() << endl; return 0; }
[---------- char 문자열 ----------] * - 글자 개수: 9 * - 사이즈: 10 * - 원본 : my string * - 사본 : my string * - 합친 것 : my string [plus something] * - 글자수 myCh1 : 10 * - Byte myCh1 : 15 [---------- string 객체 ----------] @ - string 객체 myStr1 : Smoothie Coding @ - string 객체 myStr1 : Smoothie Coding -> upgrade your code @ - string 객체 myStr2 : Smoothie Coding -> upgrade your code @ - 주소 myStr1 : 0x61feb8, @ - 주소 myStr2 : 0x61fea0 @ - 글자수 myStr1 : 5
문자열 초기화와 크기
문자열 초기화와 사이즈 설정도 차이가 있습니다. 문자열 개수를 세는 함수의 특성에 따라 사이즈가 다른데요.
초기화 후 문자열에 텍스트가 들어가면 다시 크기를 측정할 수 있습니다.
#include <iostream> #include <cstring> // C스타일 문자열 라이브러리 (char*) #include <string> using namespace std; int main() { const int size = 30; char myCharArray[size]; string myString; cout << "^ char 문자열 초기 사이즈 :" << strlen(myCharArray) << endl; cout << "^ string 문자열 초기 사이즈 :" << myString.size() << endl; cout << "--> char 문자열 한 줄을 입력하시오" << endl; cin.getline(myCharArray, size); cout << "--> string 객체를 입력하시오" << endl; getline(cin, myString); cout << "^ char 형 입력한 내용 : " << myCharArray << ": size - (" << strlen(myCharArray) << ")" << endl; cout << "^ string 형 입력한 내용 : " << myString << ": size - (" << myString.size() << ")" << endl; return 0; }
^ char 문자열 초기 사이즈 :1 ^ string 문자열 초기 사이즈 :0 --> char 문자열 한 줄을 입력하시오 Char Array --> string 객체를 입력하시오 my String ^ char 형 입력한 내용 : Char Array: size - (10) ^ string 형 입력한 내용 : my String: size - (9)
다양한 문자열 변수와 상수
C++에는 매우 다양한 문자 타입이 있습니다.
C++이 운영체제 부터 응용 프로그램까지 다양한 프로그램을 개발하는데 사용되다 보니 필요에 따라 자료형의 개수가 늘어난 것 입니다.
여기서 모든 것을 소개할 수도 없고 소개할 필요도 없습니다. C++에서 유니코드를 사용하는 법에 대해서는 별도 포스팅에서 설명할 것 입니다.
지금은 wchar_t 등 몇가지 다른 문자열 자료형이 있다는 정도를 아는 것으로 충분합니다.
#include <iostream> #include <codecvt> #include <string> #include <locale> using namespace std; int main() { wstring_convert<codecvt_utf8_utf16<wchar_t>> wchar_to_utf8; wchar_t wideChar[] = L"Wide Char Array"; const wchar_t myWChar[] = L"my const Wide Char Array"; char16_t myChar16[] = u"my Char16"; char32_t myChar32[] = U"my Char32"; wstring myWstr = L"My Wide String"; string myUtf8 = wchar_to_utf8.to_bytes(myWstr); wcout << "-- " << wideChar << endl; wcout << "-- " << myWChar << endl; wcout << "-- " << myWstr << endl; cout << "-- " << myUtf8 << endl; cout << R"(raw string "apple" "\n" "orange")" << '\n'; cout << R"+( raw string seperator )+"; return 0; }
-- Wide Char Array -- my const Wide Char Array -- My Wide String -- My Wide String raw string "apple" "\n" "orange" raw string seperator
요약
string 객체를 사용하는 C++ 문자열에 대하여 알아봤습니다.
도대체 문자열이란 무엇이냐? 라는 진지한 질문을 해봤을 때 메모리에 선형(linear) 으로 나열되어 순차성을 가진 자료구조입니다. 문자열의 값을 아스키 코드나 유니코드로 디코딩하면 인간의 언어로 이해할 수 있는 글자를 출력할 수 있는 메모리의 값이다. 라는 복잡한 설명도 가능할 정도로 깊이 이해하는 것이 필요합니다.
C++은 어렵다는 이야기가 많지만 원리적인 것만 깨달으면 외울 내용이 없기 때문에 오히려 쉬울수도 있습니다.
참고문서
C++ Strings: Using char array and string object (programiz.com)
string – C++ Reference (cplusplus.com)
std::string – C++ standard library – Cprogramming.com
C++ String tutorial (cppforschool.com)