C/C++에서 일본어를 다루고 싶습니다.
소개
C/C++에서는 일본어를 다루는 것이 어색한 문제가 된다.
bad_example1.c#include <stdio.h>
#include <string.h>
int main() {
char str[] = "日本語サンプル";
int length = strlen(str);
printf("1文字目: %c\n", str[0]);
printf("長さ: %d\n", length);
return 0;
}
$ gcc -o bad_example1 bad_example1.c
$ ./bad_example1
1文字目: �
長さ: 21
이와 같이 단순한 char형으로서 취급하면 일본어를 잘 처리할 수 없다. 뭐, 일본어가 2바이트 이상으로 표현되고 있기 때문에 당연하다고 하면 당연하지만.
그래서 C/C++에서 잘 일본어를 처리하는 방법을 두 가지 소개하고 싶다.
와이드 문자 사용
와이드 문자는 16 비트 고정 길이로 표현되는 다국어 문자 체형입니다.
C 언어에서는 wchar_t 타입을 사용하여 와이드 문자를 처리할 수 있다.
그러나 와이드 문자를 처리하려면 로케일 설정이 필요합니다. 일본어만 취급하는 경우는 ja_JP.UTF-8에 세트한다.
locale의 동작은 처리계 의존 같기 때문에, 아래의 코드는 Windows나 Mac에서는 정상적으로 동작하지 않을 가능성이 있습니다.
example1.c#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
int main() {
setlocale(LC_CTYPE, "ja_JP.UTF-8");
char str1[] = "(゚∀゚)( ゚∀)超( ゚)絶( )大(゚ )興(∀゚ )奮(゚∀゚)━キター!!!!";
// 十分なメモリ領域を確保
size_t capacity = strlen(str1) + 1;
wchar_t *str2 = (wchar_t *)malloc(sizeof(wchar_t) * capacity);
// char -> wchar_tの変換
int result = mbstowcs(str2, str1, capacity);
if (result <= 0) {
fprintf(stderr, "マルチバイト文字列の変換に失敗\n");
return EXIT_FAILURE;
}
printf("バイト長: %lu\n", capacity - 1);
printf("長さ: %d\n", result);
// 十分なメモリ領域を確保
capacity = wcslen(str2) * 6 + 1;
char* str3 = (char *)malloc(sizeof(char) * capacity);
// wchar_t -> charの変換
result = wcstombs(str3, str2, capacity);
if (result <= 0) {
fprintf(stderr, "ワイド文字列の変換に失敗");
return EXIT_FAILURE;
}
printf("文字列: %s\n", str3);
printf("1文字目: %lc\n", str2[0]);
}
$ gcc -o example1 example1.c
$ ./example5
バイト長: 86
長さ: 44
文字列: (゚∀゚)( ゚∀)超( ゚)絶( )大(゚ )興(∀゚ )奮(゚∀゚)━キター!!!!
1文字目: (
여러가지 조사했지만, UTF-8의 경우는 최대로 1 문자 6 바이트를 사용해 나타내지므로, char형으로 변환할 때는 6배의 메모리를 확보해 두면 문제 없다.
wchar_t형의 변수를 출력하는 경우, 문자의 경우의 서식 캐릭터 라인은 %lc, 캐릭터 라인의 경우는 %ls로 하면 된다.
그리고, wprintf나 wcout는, printf나cout와 병용하면 거동이 이상해지는 일이 있기 때문에, 가능한 한 사용하지 않는 편이 무난하다.
일단 char형으로 변환하고 나서 출력하는 것이 가장 안전할 것이다.
utfcpp 사용
이쪽은 C++ 한정이지만, wchar_t형으로 변환하지 않고 멀티 바이트 캐릭터 라인을 취급할 수 있으므로 편리.
utfcpp : htps : // 기주 b. 코 m / 네 mt f / u tfc p
이것을 사용하면, 문자열의 길이나 문자 위치의 이터레이터 등을 간단하게 구성할 수 있다.
example2.cpp#include <iostream>
#include <cstring>
#include <cstdint>
#include <utf8.h>
int main() {
const char* str1 = u8"明日天気にな〜れ";
const char* it = str1;
const char* end = str1 + strlen(str1);
// 文字列の長さを取得
int length = utf8::distance(it, end);
std::cout << "長さ: " << length << std::endl;
std::cout << std::hex;
while (it < end) {
// イテレータを1文字分すすめる
std::uint32_t code = utf8::next(it, end);
// 該当位置の文字コードを出力
std::cout << code << std::endl;
}
return 0;
}
$ g++ example2.cpp -o example4
$ ./example2
長さ: 8
660e
65e5
5929
6c17
306b
306a
301c
308c
그 밖에도 편리한 함수가 많이 있으므로, Github 쪽을 참조해 주었으면 한다.
요약
C/C++에서도 일본어 취급할 수 있어!
Reference
이 문제에 관하여(C/C++에서 일본어를 다루고 싶습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Kogia_sima/items/80598029683175755efd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "日本語サンプル";
int length = strlen(str);
printf("1文字目: %c\n", str[0]);
printf("長さ: %d\n", length);
return 0;
}
$ gcc -o bad_example1 bad_example1.c
$ ./bad_example1
1文字目: �
長さ: 21
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
int main() {
setlocale(LC_CTYPE, "ja_JP.UTF-8");
char str1[] = "(゚∀゚)( ゚∀)超( ゚)絶( )大(゚ )興(∀゚ )奮(゚∀゚)━キター!!!!";
// 十分なメモリ領域を確保
size_t capacity = strlen(str1) + 1;
wchar_t *str2 = (wchar_t *)malloc(sizeof(wchar_t) * capacity);
// char -> wchar_tの変換
int result = mbstowcs(str2, str1, capacity);
if (result <= 0) {
fprintf(stderr, "マルチバイト文字列の変換に失敗\n");
return EXIT_FAILURE;
}
printf("バイト長: %lu\n", capacity - 1);
printf("長さ: %d\n", result);
// 十分なメモリ領域を確保
capacity = wcslen(str2) * 6 + 1;
char* str3 = (char *)malloc(sizeof(char) * capacity);
// wchar_t -> charの変換
result = wcstombs(str3, str2, capacity);
if (result <= 0) {
fprintf(stderr, "ワイド文字列の変換に失敗");
return EXIT_FAILURE;
}
printf("文字列: %s\n", str3);
printf("1文字目: %lc\n", str2[0]);
}
$ gcc -o example1 example1.c
$ ./example5
バイト長: 86
長さ: 44
文字列: (゚∀゚)( ゚∀)超( ゚)絶( )大(゚ )興(∀゚ )奮(゚∀゚)━キター!!!!
1文字目: (
#include <iostream>
#include <cstring>
#include <cstdint>
#include <utf8.h>
int main() {
const char* str1 = u8"明日天気にな〜れ";
const char* it = str1;
const char* end = str1 + strlen(str1);
// 文字列の長さを取得
int length = utf8::distance(it, end);
std::cout << "長さ: " << length << std::endl;
std::cout << std::hex;
while (it < end) {
// イテレータを1文字分すすめる
std::uint32_t code = utf8::next(it, end);
// 該当位置の文字コードを出力
std::cout << code << std::endl;
}
return 0;
}
$ g++ example2.cpp -o example4
$ ./example2
長さ: 8
660e
65e5
5929
6c17
306b
306a
301c
308c
C/C++에서도 일본어 취급할 수 있어!
Reference
이 문제에 관하여(C/C++에서 일본어를 다루고 싶습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Kogia_sima/items/80598029683175755efd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)