文字→文字コードの変換について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
doss

文字→文字コードの変換について

#1

投稿記事 by doss » 10年前

内容はタイトルの通りなのですが、探せども探せども 文字コード→文字しか出てきません。
具体的に何がしたいのかというと、ひらがなカタカナ54音の画像の分割して読み取り書き込んだ文字列によってそれに合った画像を表示していくというものなのですが。口では説明しにくいので実際にソースを書いてみたいと思います。

コード:

#include <DxLib.h>
#include <stdio.h>
#define CHARCODE "54音.jpg"
void CreateCharCode();
void DrawString(const char*);
int n[240];
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
	DxLib::ChangeWindowMode(true);
	DxLib::DxLib_Init();
        //54音+aの表示
CreateCharCode();
count = 0;
        DrawString("もじれつ");
	DxLib::WaitKey();
	DxLib::DxLib_End();
}

void CreateCharCode(){
	
	DxLib::LoadDivGraph(CHARCODE,240,24,11,int(400/24),int(240/10),n);
	int count=0;
	for(int i=0; i<24; i++)
		for(int j=0; j<11; j++ ){
			DxLib::DrawGraph(int(450/24)*i,int(270/10)*j,n[count],NULL);
			count++;
		}
}

void DrawString(const char* s){
        int c = 文字を文字コードに変換する関数(s[i])-177;
        if( c = 0 ){                      //'あ'の画像の表示
             Draw( 10*count , 350 , n[c] , NULL );
        }
}
といったことができればうれしいです。
技術不足でうまく伝わるのを祈るしかないのですが、お願いします。

アバター
milfeulle
記事: 47
登録日時: 10年前
住所: マリーランド
連絡を取る:

Re: 文字→文字コードの変換について

#2

投稿記事 by milfeulle » 10年前

日本語の入った文字列から日本語1文字づつ読み込んで、それ(文字コード)に対応した画像を表示しようとされているのですね。といってもC++で「文字」を表す表現はたくさんあり、それらは符号化方式によって異なります。今回は“ひらがなカタカナ54音”だけ用いられ、どの方法を選んでも大変ではないと思いますので、C++でワイド文字を扱って解決したいと思います。
オフトピック
Windowsでプログラミングをする上で文字はTCHAR型を使うと思います。例えばID3DXFont::DrawTextは引数にLPCTSTR pStringを取りますが、これはTCHARのポインタです。これに限らずWindowsのAPI群はどれもTCHARを扱います。これはプロジェクトの文字の種類の設定により、マルチバイト文字とUnicodeを切り替えられるようにしているためです。どちらもサポートする必要がある、或いはUnicodeで固定したくない場合はこの型を使うといいです。(参考URI : その4 charとUnicodeとワイド文字をごっちゃにしないために, _T("")マクロについて)
日本語を扱うには2byte以上必要となるので、2byte以上のメモリとグラフィックハンドルが格納された配列nのインデックスとの対応が必要となります。そこで、それらの対応にstd::mapを利用することにします。STLが使用できない事情があるなら「ハッシュテーブル C++」で検索して下さい。

以下の例では、日本語1文字とグラフィックハンドルの格納された配列のインデックスを対応づけたcharactor_to_handleを使用して、文字列1文字1文字をグラフィックハンドルに変換する例です。今回の場合は限定された日本語を使うことが想定されているため、wchar_t固定で問題ないです。また、面倒ながら1つ1つインデックスを指定する必要があります。これらのインデックスは画像の左上から右に向かって順に割り当てられるので簡単に分かると思います。

コード:

#include <iostream>
#include <map>

using namespace std;

int main() {
	wchar_t str[] = L"おえいうあ";
	map<wchar_t, int> charactor_to_handle = {
		{ L'あ', 0 },
		{ L'い', 1 },
		{ L'う', 2 },
		{ L'え', 3 },
		{ L'お', 4 },
	};
	int n[256] = { 100, 200, 300, 400, 500 };
	
	for(int i = 0; i < wcslen(str); ++i) {
		wcout << n[charactor_to_handle[str[i]]] << endl;
	}

	cin.get();
	return 0;
}
strで日本語1文字を取得し、charactor_to_handle[str]でその日本語に対応したnのインデックスを取得します。このインデックスを指定してグラフィックハンドルが格納された配列nからハンドルを読み出しています。個々では適当に100, 200, ...と割り当てて実行結果が分かりやすいようにしました。

実行結果は、
500
400
200
300
100

となります。

もしも任意の日本語に対応しようと思うと少し複雑です。というのも、Unicode、ここで用いられるUTF-16にはサロゲートペアというものがあって、2byteで表現しきれない追加の文字を4byteで表現することがあるからです。これらの文字に対応しようと思うと処理が複雑になるでしょうが、今回は関係ありませんね!

結局ポイントは、char型の配列ではなくwchar_t型(TCHAR型)の配列にすることで、配列の1つ1つに文字が格納されるようにするところです。ご質問通りの「 文字→文字コード」はしていませんが、wchar_tで扱うことにより直接配列のインデックスを指定することで文字コードが得られます。但し上記の通りサロゲートペアは対象外です。
ζ*'ヮ')ζプログラミングはみんなで奏でるシンフォニー

doss

Re: 文字→文字コードの変換について

#3

投稿記事 by doss » 10年前

コード:

#include <iostream>
#include <map>
 
using namespace std;
 
int main() {
    wchar_t str[] = L"おえいうあ";
    map<wchar_t, int> charactor_to_handle = {
        { L'あ', 0 },
        { L'い', 1 },
        { L'う', 2 },
        { L'え', 3 },
        { L'お', 4 },
    };
    int n[256] = { 100, 200, 300, 400, 500 };
    
    for(int i = 0; i < wcslen(str); ++i) {
        wcout << n[charactor_to_handle[str[i]]] << endl;
    }
 
    cin.get();
    return 0;
}
このソースを実行してみたところ
.cpp(8): error C2552: 'charactor_to_handle' : 初期化子リストによる個別の識別子の初期化に誤りがあります。
というのエラーが出てしまったのですが、そちらでは確認されましたでしょうか。
もしも環境等の違いであれば、ここを変更しないと機能しない等と言っていただけると助かります。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 文字→文字コードの変換について

#4

投稿記事 by みけCAT » 10年前

doss さんが書きました:

コード:

#include <iostream>
#include <map>
 
using namespace std;
 
int main() {
    wchar_t str[] = L"おえいうあ";
    map<wchar_t, int> charactor_to_handle = {
        { L'あ', 0 },
        { L'い', 1 },
        { L'う', 2 },
        { L'え', 3 },
        { L'お', 4 },
    };
    int n[256] = { 100, 200, 300, 400, 500 };
    
    for(int i = 0; i < wcslen(str); ++i) {
        wcout << n[charactor_to_handle[str[i]]] << endl;
    }
 
    cin.get();
    return 0;
}
このソースを実行してみたところ
.cpp(8): error C2552: 'charactor_to_handle' : 初期化子リストによる個別の識別子の初期化に誤りがあります。
というのエラーが出てしまったのですが、そちらでは確認されましたでしょうか。
もしも環境等の違いであれば、ここを変更しないと機能しない等と言っていただけると助かります。
このコードはC++11にしないとコンパイルできないようですね。
https://ideone.com/tOaPHH
https://ideone.com/Xolezy
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

doss

Re: 文字→文字コードの変換について

#5

投稿記事 by doss » 10年前

やはり、文字列→文字→文字コードはVC環境では難しいのでしょうか。
出来たらVC環境内でもできる方法があれば教えていただけませんでしょうか

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 文字→文字コードの変換について

#6

投稿記事 by みけCAT » 10年前

素直にこれではダメですか?

コード:

#include <iostream>
#include <map>
 
using namespace std;
 
int main() {
	wchar_t str[] = L"おえいうあ";
	map<wchar_t, int> charactor_to_handle;
	charactor_to_handle[L'あ'] = 0;
	charactor_to_handle[L'い'] = 1;
	charactor_to_handle[L'う'] = 2;
	charactor_to_handle[L'え'] = 3;
	charactor_to_handle[L'お'] = 4;
	int n[256] = { 100, 200, 300, 400, 500 };

	for(int i = 0; i < wcslen(str); ++i) {
		wcout << n[charactor_to_handle[str[i]]] << endl;
	}

	cin.get();
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

doss

Re: 文字→文字コードの変換について

#7

投稿記事 by doss » 10年前

みけCATさん、ありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る