오늘 포스팅할 내용은 로컬라이징에 관련된 내용이다.

프로젝트를 다른 언어로 번역하는 과정에서 가장 큰 이슈는 

아마 번역한 문장의 길이와 UI의 부적합이 아닐까 생각한다.

한글로 썼을때 짧은 문장이 다른 언어로 번역되면서 매우 긴 문장으로 바뀌는 경우가 많기 때문이다.

이럴때 어떤 나라의 언어던지 원하는 글자 수에서 끊고 뒤에 [...]을 이어 붙여주는 함수가 있다면 좋겠다는 생각에 구현해보았다.



먼저 함수의 역할은 다음과 같다.

- std::string CutStr(std::string* targetString, size_t length)

- 문장과 자르고 싶은 길이를 입력받고 출력은 잘린 문자열 뒤에 [...]이 붙어져 있어야 할 것이다.

ex 1) CutStr("ABCDEFGHIJ", 5)          =>  "ABCDE..."

ex 2) CutStr("동해물과백두산이", 5)      =>  "동해물과백..."

ex 3) CutStr("A동B해C물D과E백F", 5)    =>  "A동B해Z..."



사실 영어의 경우 문자의 길이가 곧 바이트 수이기 때문에 strlen함수로 길이를 알아내어 간단하게 끊을 수 있다.

하지만 한글이나 일본어 등은 3바이트이기 때문에 [가나다] = 9가 된다. 

또 영어나 한글을 같이 쓸경우 각 문자의 바이트수를 알아내어 계산해야 한다. 

구현한 결과는 아래와 같다.


코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
 
using namespace std;
 
string cutStr(string targetString, size_t limitNum)
{
    // 원래의 문장 저장
    string curString = targetString;
    
    // 제한길이까지의 바이트 수
    size_t byteNum = 0;
    char strArr[1024= {0,};
    
    // 각 문자가 어떤 언어인지 알 수 있게 char형으로 저장
    strcpy( strArr, curString.c_str() );
    
    // 각 배열에 저장되어 있는 값이 아스키 코드값이 존재하는 지에 따라 문자구분.
    for(size_t count = 0; count < limitNum ; count++)
    {
        // 아스키값이 없으면 3바이트로 처리
        if((unsigned char)strArr[byteNum] & 0x80)
        {
            byteNum += 3;
        }
        // 아스키값이 있으면 1바이트로 처리
        else
        {
            byteNum += 1;
        }
    }
    // 전체 바이트 수가 제한 길이까지의 바이트 수 보다 크면 문장을 잘라야 함
    if(curString.length() > byteNum)
    {
        // 제한길이까지의 바이트 수만큼 문장을 자른다.
        string cuttedString = targetString.substr(0, byteNum);
        // 뒤에 [...]을 붙여준다.
        cuttedString.append("...");
        return cuttedString;
    }
    // 자를 필요가 없으면 그냥 문장 리턴
    return curString;
}
 
int main()
{
    string string1 = "ABCDEFG";
    string string2 = "가나다라마바";
    string string3 = "A가B나C다D라";
    
    printf("%s\n", cutStr(string1, 5).c_str());
    printf("%s\n", cutStr(string2, 5).c_str());
    printf("%s\n", cutStr(string3, 5).c_str());
}
cs



결과

1
2
3
ABCDE...
가나다라마...
A가B나C...
cs



원리는 0x80 과 문자배열의 요소의 &연산(1000.0000 & 111.1111)으로 해당 문자가 1 ~ 127  범위안 (아스키 코드)인지 판단하여 범위 안이면 1바이트 밖이면 3바이트 로 계산하여 제한 길이까지의 바이트 수를 저장한다. 

그후 구한 바이트 수가 문자열의 총 바이트 수보다 작다면 문자열을 자른후 [...]을 붙인다.


아스키코드표의 문자들을 제외하면 전부 3바이트로 처리하니 정확한 것은 아니지만 UTF-8인코딩 에서 3바이트로 처리되는 언어들에서는 충분히 사용가능할 것이다.

'All > C++' 카테고리의 다른 글

자주 사용하는 STL function  (0) 2016.11.28
operator new / operator delete  (0) 2016.03.14
메모리 누수 검사  (0) 2015.12.29
가변인자 로그 출력함수  (0) 2015.12.29
RValue와 LValue  (2) 2015.12.28

+ Recent posts