C++ 문자열(String) 소개 | C++ 자습서 8

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 – Tutorialspoint

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)

Leave a Comment