Qaupot Blog
Software Engineering, Trip

403. 문자열

🕐 Fri, 07 Feb 2014 09:00:00 GMT 🕓 Tue, 24 Aug 2021 01:17:00 GMT

문자열 정의

C/C++에서 문자열이란, 단순한 char 자료형(혹은 wide char)의 배열입니다.

  • C++에서 std::string 클래스가 등장했으나, 이 역시 내부는 구현은 다르지 않습니다.

ANSI 문자열 코드

char 형은 1byte 의 자료형입니다.

위의 표는 ANSI 의 문자열 코드표입니다.

문자열, char 형이라고 해서 숫자가 아닌 무엇인가가 들어가는 것은 아니며, 위의 코드표에 해당하는 숫자에 대해 해당하는 문자로 처리하기로 규정 되어 있습니다.

만약 Hello 라는 문자열이 있다면 72 101 108 108 111의 숫자가 char 형 배열에 각각 들어 있게 됩니다. 하나의 char 형 변수는 하나의 '문자' 에 대응합니다.

이 자체로도 Hello 라는 문자열에 대응 되지만, 안전하게 '문자열' 을 의미하려면 가장 마지막에 NULL 문자라고 불리는, 0의 값을 넣어주어야 합니다.
따라서 Hello 라는 문자열이면, 72 101 108 108 111 0을 사용합니다.

이렇게 마지막에 NULL 문자를 넣는 이유는, 메모리는 길게 늘어선 평면 구조(flat)이기 때문입니다.

  • 어느 지점에서 문자열이 끝났다는것을 표기하지 않으면 남은 모든 주소의 메모리를 계속해서 문자열로 읽어냅니다.
  • 끝에 NULL 문자를 넣음으로써, 이 부분이 문자열의 끝이 되는 지점이라는 것을 표기해주는 것입니다.

Multibyte 와 Unicode

컴퓨터의 초창기에는 영어 외의 다른 언어에는 관심이 없었지만, 점점 확산되면서 여러 언어를 지원하기 시작했습니다.

그 형태를 Multibyte 와 Unicode 로 나눠보며, 한국어를 예제로 들겠습니다.

Multibyte

Multibyte 는 과거 UNICODE 가 만들어 지기 전에 사용되던 코드들입니다.
한국어는 보통 KS X 1001과 EUC-KR 이라는 별도의 완성형 2byte 코드표를 사용합니다.

  • 완성형은 가,나,다,라 같이 하나의 문자가 하나의 숫자에 매칭되는 방법
  • 조합형은 ㄱㄴㄷ등을 특정숫자에 매칭시킨뒤 그들을 합쳐 하나로 만드는 방법

Multibyte 는 각 지역/국가별로 사용하는 언어에 따라 독자적인 규격을 사용하기에 호환이 다소 까다롭습니다.
프로그램을 실행시켰을때 깹뷁땝꺕 같은 문자가 나타나는 현상이 멀티바이트 타 문자열셋으로 만들어진 프로그램을 실행시켰을때 나타나는 현상입니다.

그러나 이러한 단점에도 불구하고 유니코드 등장 이전에 작성된 프로그램 역시 많기에, 여전히 폭 넓게 사용되고 있습니다.
C/C++에서 사용할때는 char CharArray[40] = "가나다라" 같은 형태로 사용하시면 되며, 한글 한 글자에 2 byte 를 사용합니다.

Unicode

UNICODE 는 국제표준으로 제정된 문자열 코드셋입니다.

  • 각 지역별로 따로 사용되던 문자크기를 2 byte 로, 형태를 완성형으로 통일했습니다.
  • 세계의 모든 문자, 글자에 대해 하나씩 숫자를 부여하고 있으며, 2 byte 를 사용하기 때문에, 65536개의 글자(2의 16승)를 표현할 수 있습니다.

UTF-16 (2byte) 으로 시작하였으나, 추후 문자가 늘어남에 따라, UTF-32 (4byte) 로 확장되었으며, UTF-8 (1byte) 는 byte 수를 가변적으로 사용합니다.

그 중 한자가 40%, 한글이 17%정도를 차지하고 있으므로, 극동아시아권 문자가 상당히 많은것을 알 수 있습니다.

C/C++에서 표현할때는 wchar_t형을 사용합니다. wide char 형이라는 의미이며, 이 자료형은 2byte 입니다.

wchar_t WCharArray[20] = L"가나다라"
  • 유니코드라는것을 표현하기 위해서 문자열 앞에 L을 붙여 표기해줍니다.
  • 유니코드 처리를 위해 wprintf 를 비롯한 함수들이 별도로 존재합니다.

각 문자열 셋의 호환

서로 다른 문자열 셋을 호환시키기는 조금 까다롭습니다.
printf 함수는 wchar 형을 받지 않으며, wprintf 함수는 char 형을 받지 않습니다.

또한 서로 다른 문자 코드표를 사용하므로 같은 숫자라도 전혀 다른 의미를 가지며, 직접 표를 이용해 변환을 하려면 복잡한 일이 됩니다.

이에 OS 제공 업체들에서는 편의 함수로 문자열 셋을 변환하는 함수들을 제공하기도 합니다.

Exercise

여기에서는 멀티바이트 및 ANSI 코드의 형태를 가진 문자열을 다루는 몇 가지 함수만 다룹니다.

#include <stdio.h>
#include <string.h>

int main(int argc,char** argv)
{
    char CharArray[30] = "Printf : %d %dn";

    printf(CharArray,10,20);
    printf("CharArrayLength : %d\n",strlen(CharArray));

    char ResultCharArray[20];

    strcpy(ResultCharArray,"Strcpy");
    printf("ResultChar After strcpy :%s\n",ResultCharArray);

    strcat(ResultCharArray,"Strcat");
    printf("ResultChar After strcat :%s\n",ResultCharArray);

    printf("strcmp1 : %d\n",strcmp("ABCDEFG","ABCDEFG") );
    printf("strcmp2 : %d\n",strcmp("ABCDEFG","abcdefg") );
    printf("strcmp3 : %d\n",strcmp("abcdefg","ABCDEFG") );
    return 0;
}

charArray 에 문자열을 대입하고, printf 함수의 인수를 채워 출력해봅니다.

strlen 함수를 호출합니다.

  • 인수로 들어온 문자열의 길이를 알려주는 함수입니다. NULL 문자가 등장할 때 까지의 길이를 세어 돌려줍니다.
  • 마찬가지로 한글의 경우 한글자당 2의 길이를 가집니다.

strcpy 함수를 호출합니다.

  • char 배열에 지정된 문자열을 복사하는 함수입니다.
  • 첫번째 인수가 dest 로 복사한 결과값이 위치할 곳이며, 두번째 인수가 src 로 복사할 값입니다.
  • src 측에서 NULL 문자가 나올때까지의 값을 dest 측에 복사합니다. dest 는 src 보다 커야하며, 그렇지 않으면 에러가 발생합니다.

그리고 printf 를 이용해서 그 결과를 출력합니다.

  • %s는 문자열로 치환된다는 의미입니다.

strcat 함수를 호출합니다.

  • 이 함수는 지정된 문자열을 뒤에 덧 붙이는 함수입니다. 첫번째 인수가 dest 이며, 두번째 인수가 src 입니다.
  • dest 에서 NULL 문자를 떼어 버리고 그 뒤에 src 를 복사해 넣습니다. dest 는 dest+src 의 크기 이상을 가지고 있어야합니다.

strcmp 함수를 호출합니다.

  • 이 함수는 두개의 문자열을 비교하는 함수입니다. 첫번째 인수는 s1, 두번째 인수는 s2입니다.
  • s1이 s2보다 작다면 음수를, s1과 s2가 같다면 0을, s1이 s2보다 크다면 양수를 돌려줍니다.

문자열을 다루는 함수는 C의 경우 string.h라는 파일에 정의가 포함되어 있습니다.
함수들은 대부분 str~으로 시작하는 함수명들을 가집니다.

이 블로그는 개인 블로그입니다. 게시글은 오류를 포함하고 있을 수 있지만, 저자는 오류를 해결하기 위해 노력하고 있습니다.
게시글에 별도의 고지가 없는 경우, 크리에이티브 커먼즈 저작자표시-비영리-변경금지 4.0 라이선스를 따릅니다.

This blog is personal blog. published posts may contain some errors, but author doing efforts to clear errors.
If post have not notice of license, it under creative commons Attribution-NonCommercial-NoDerivatives 4.0.