C++ 문자열 | C++ 자습서 7

C++ 문자열(char)

C++에서 문자열을 다루는 방법을 이해할 수 있다면 현존하는 거의 모든 프로그래밍 언어에서 문자열을 다루는 방법을 터득하는 것과 같습니다.

문자열은 문자(Character)의 열(Array)입니다. C++의 문자는 아스키(ASCII) 코드를 사용합니다. 즉 문자열은 아스키코드를 연속적으로 나열한 것입니다. 그런데 한글이나 중국어 등 국가의 언어는 글자수가 많아서 C++ 의 char 형에는 들어가지 않습니다. 기본 아스키 코드는 영문만 커버합니다.

전세계의 문자를 표현하는 유니코드에 대해서는 다른 포스팅에서 다루고 여기서는 아스키 코드를 사용한 영문 문자열에 대하여 설명하겠습니다. 유니코드는 결국 표현할 수 있는 문자의 수가 늘어난 것인데 문자를 표현하는 원리 자체는 아스키 코드나 유니코드나 별 차이가 없습니다.

어떤 한 문자가 있다면 그 문자를 숫자로 저장할 수 있는 코드로 바꾼다는 아이디어가 핵심입니다. 모든 프로그램에서 문자열은 가장 중요한 파트입니다. 우리가 프로그램을 시작하고 사용하고 끌 때 모니터에 있는 글자를 보고 따라갑니다. 컴퓨터의 언어가 0과 1이라면 인간은 문자열로 일을 처리하거나 소통을 할 수 있습니다. 문자열 체계가 중요해지고 복잡해지는 것은 어떻게 보면 당연한 일입니다.

문자열을 다루면서 생각할 부분은 기계의 언어는 0과 1이고 인간의 언어는 영어, 한글과 같은 문자열이다. 라는 부분입니다. 이 개념으로 구분하고 프로그래밍을 하면 시간이 갈수록 컴퓨터 구조의 본질을 이해할 수 있습니다.

문자열 초기화

문자열 초기화는 배열의 초기화 형식과 같습니다. 문자열 자체가 배열입니다. 문자열의 끝에는 ‘\0’ 문자가 들어가는데요. 아스키코드로는 0입니다. 마지막에 0을 둠으로써 문자열의 끝을 알 수 있습니다.

마지막에 0이 없으면 언제 문자열이 끝인지 알 수가 없는 경우가 생깁니다. 따라서 배열을 선언하더라도 마지막에 0이 들어갈 수 있는 1바이트가 필요합니다.

char str[10] 이라 해놓고 str[0], str[1] 이렇게 한글자씩 문자열을 대입하는 것은 시간이 너무 오래 걸리니까 보통 “문자열” 의 형식으로 초기화 합니다. 이 경우에도 컴파일러가 끝에 0을 추가해주기 때문에 문자열의 끝이 어디인지 알 수 있습니다. 또 문자열의 끝과 배열의 크기는 다른 것 입니다.

#include <iostream>

using namespace std;

int main()
{
    // C언어 스타일 문자
    char name[6] {'j','e','r','r','y','\0'};
    cout << name << endl;

    // 문자열이 아닌 것, 결과 예측이 어렵다.
    // 0이 없다
    char product[3] {'c','o','m'};
    cout << product << endl;

    //  문자열 초기화 방법
    char myStr[20] = "Hello my Friend!";
    cout << myStr << endl;

    // 컴파일러가 배열의 크기를 알아서 계산한다.
    char yourStr[] = "Greetings!";
    cout << yourStr << endl;

    return 0;
}
jerry
comjerry
Hello my Friend!
Greetings!

아래의 예제에서는 char 배열을 활용한 다양한 문자열 사용법입니다. char 에서 주의할게 ‘A’ 를 저장하면 실제로 들어가는 값는 65입니다. cout 함수는 char 형 배열을 만나면 이를 문자열로 파악해서 숫자가 아니라 문자로 출력시킵니다. 역시 마지막이 어딘지는 0이 있는 곳을 기준으로 알 수 있습닌다.

#include <iostream>

using namespace std;

int main()
{
    // 문자 하나 (Character)
    char myChar = 'A';

    cout << myChar << endl;
    cout << (int)myChar << endl;

    // 문자열 (배열)
    char myStr[] = "-- My String";
    
    cout << myStr << endl;

    // 오류가 난다. const char* to char 
    // char yourStr = "-- Your String";

    // 배열 요소 하나에 한개씩 아스키 코드가 저장된다.

    char hisStr[] = "String";
    cout << hisStr << endl;

    cout << hisStr[0] << ", ";
    cout << hisStr[1] << ", ";
    cout << hisStr[2] << ", ";
    cout << hisStr[3] << ", ";
    cout << hisStr[4] << ", ";
    cout << hisStr[5] << endl;

    // 포인터를 사용 (ISO 에서는 변환을 금하고 있다)
    char* herStr = "Her Story";
    cout << herStr << endl;

    return 0;
}
A
65
-- My String
String
S, t, r, i, n, g
Her Story

문자열 입력(white space)

문자열의 입력에는 cin (표준 키포드 입력)을 사용합니다.

cin 은 공백문자(스페이스, 개행문자, 탭 등)를 입력의 마지막으로 간주하기 때문에 한단어만 입력 받습니다. 두 단어를 쓰면 앞쪽 단어를 저장하고 나머지 한 단어는 입력큐에 남아있습니다. (다음에 cin 이 나오면 바로 입력큐에서 가져갑니다.)

#include <iostream>

using namespace std;

int main()
{
    const int size = 30;

    char name[size];
    char country[size];

    // cin 은 공백문자를 기준으로 입력받는다

    cout << "what's your name?" << endl;
    cin >> name;

    cout << "where are you from?" << endl;
    cin >> country;
    
    cout << "[------------------------]";
    cout << "name : " << name << endl;
    cout << "country : " << country << endl;

    return 0;
}
what's your name?
master ken
where are you from?
[------------------------]name : master
country : ken

문자열 입력(getline)

getline 을 하용하면 한 줄을 통째로 받을 수 있습니다. 개행문자 ‘\n’를 입력하기 전까지 여러개 단어라도 입력 받습니다.

#include <iostream>

using namespace std;

int main()
{
    const int size = 30;
    char country[size];
    char city[size];

    cout << "what is your country?\n";
    cin.getline(country, size);
    cout << "what is your city?\n";
    cin.getline(city, size);

    cout << "your country: " << country << endl;
    cout << "your city   : " << city << endl;

    return 0;
}
what is your country?
United States
what is your city?
Los Angeles
your country: United States
your city   : Los Angeles

Los Angeles 같이 두 단어도 제대로 입력을 받습니다.

문자열 입력(get)

cin.get 은 개행문자 \n 를 입력 큐에 남겨둡니다. 문자열을 입력받다보면 char 배열의 크기를 넘어가서 더 이상 읽을 수 없는 경우가 생기는데 get메소드로 에러체킹을 할 수 있습니다.

    cout << "what is your country?\n";
    cin.get(country, size);
    cin.get();
    cout << "what is your city?\n";
    cin.get(city, size).get();

    cout << "your country: " << country << endl;
    cout << "your city   : " << city << endl;

메소드를 두개 붙인 것은 입력큐에 남은 \n을 가져가기 위해서 입니다.

유니코드 문자열(wchar_t)

C++에는 자료형이 엄청 많은데요. 그중 문자를 다루는 자료형(Data Type)또 꽤 많습니다. 여기서 다 소개할 순 없으나 char가 1바이트인 것에 비하여 wchar_t 는 2바이트로 영어뿐 아니라 세계의 언어들도 유니코드로 사용이 가능합니다.

    const int size = 10;
    wchar_t country[size];
    wchar_t city[size];

    cout << "what is your country?\n";
    wcin.get(country, size).get();
    cout << "what is your city?\n";
    wcin.get(city, size).get();

    wcout << "your country: " << country << endl;
    wcout << "your city   : " << city << endl;
what is your country?
영국
what is your city?
런던 시
your country: 영국
your city   : 런던 시

한글의 사용법은 영어에 비해서 좀더 복잡한데요. 유니코드 체계가 자리를 잡기 전에도 컴퓨터에서 한글을 사용해야 했기 때문에(1970년대에 최초로 한글 폰트가 보급되었다고 함) 인코딩 방식이 몇 개가 있습니다.

최근에야 거의 UTF-8 로 호환이 되는 추세지만 아직도 웹페이지에서 EUC-KR를 사용하는 경우도 볼 수 있고, 윈도우즈 명령 프롬프트의 기본 인코딩은 CP949 (코드 페이지 949)입니다. 보통 C++ 프로그램을 테스트할 때 콘솔을 많이 사용하는데 윈도우즈 계열을 사용하다보면 UTF-8로 저장된 한글 텍스트는 명령 프롬프트 cmd 에서 chcp 65001로 바꿔줘야 출력이 되는 경우도 있습니다.

한글을 처리하는 방법에 대해서는 차차 배우기로 하고 우선 아스키 코드를 자유자재로 사용할 수 있도록 충분히 실습을 하는게 좋습니다.

요약

C++에서 char 배열로 문자열을 사용하는 방식은 과거 C언어 스타일입니다. C++로 바뀌고 더 편리한 string클래스를 사용할 수 있으므로 char 문자열을 사용할 일은 줄어들 것 입니다. 하지만 C와 C++을 이어주는 연결부분을 배워두는 것도 필요합니다.

C와 C++의 차이점은 여러가지가 있지만 컴퓨터 소프트웨어가 작동하는 원리는 같습니다. 다른 언어와는 다르게 C++을 하면 컴퓨터에 대한 근본적인 질문을 많이 하게 될 것 입니다.

참고문서

Convert character array to string in C++ 문자열 – GeeksforGeeks

C++ 문자열 : Using char array and string object (programiz.com)

Convert String to Char Array and Char Array to String in C++ – JournalDev

Char array to string in C++ – javatpoint

convert char array to string – C++ 문자열 (cplusplus.com)

Character sequences – C++ 문자열 Tutorials (cplusplus.com)

C++ Convert Char Array to String (tutorialkart.com)

Leave a Comment