質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Q&A

解決済

3回答

1501閲覧

JISの文字コード変換

LS_Takao

総合スコア13

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

0グッド

0クリップ

投稿2021/05/20 06:36

編集2021/05/20 07:02

JISの文字コードで格納されたデータをQtで表示できるように文字コードの変換を試しているのですが、上手くいきません。

試したコードは以下の通りです。

wchar_t JIS_DATA[100];
上記の領域にJISコードの2バイト文字列(ABCDEFGH)が格納されています。

wchar_t *pData = &JIS_DATA[0];
QTextCodec *pCodec = QTextCodec::codecForName("ISO-2022-JP");
QByteArray aJisStr = QByteArray((const char *)pData);
QString strWork = pCodec->toUnicode(aJisStr);

strWorkの内容は「A#B#C#D#E#F#G#H#」となってしまいます。
strWorkに「ABCDEFGH」と変換したいですが...

御教授の程、宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

itagagaki

2021/05/20 06:51

Qtは知らないんですけど、 wchar_t *pData = &JIS_DATA[0]; // ABCDEFGH って、ISO-2022-JPでエンコードされたバイトコード?をwchar_t*で指しているのが不自然に思うのですが、そのへんどうなんでしょう?
LS_Takao

2021/05/20 07:08

ご質問ありがとうございます。 JIS_DATA[]はwchar_t型の配列で別途定義しているという前提です。 質問内容を補いました。 気がかりなのは、toUnicode()がQByteArrayのデータを扱うため、wchar_tをQByteArrayに変換しているのですが、QByteArrayは「const char *」でなければならず、wchar_tを(const char *)でキャストしています。
itagagaki

2021/05/20 07:15

ISO-2022-JPはバイト列なので、それをどうしてwchar_tで扱っているのかがそもそも不思議なんですけど、ISO-2022-JPの各バイトに1バイトの0を足して2バイトにして表現しているのだとしたら、それはISO-2022-JPではないので、ISO-2022-JPからの変換器として作成されたpCodecが正しく動作しないのは当たり前のような気がするのですが…。
LS_Takao

2021/05/20 07:33

ISO-2022-JPで全角「A」は、文字コードで表現すると「0x2341」のように、2バイトになると解釈しているのですが、認識が誤っているのでしょうか?
itagagaki

2021/05/20 07:43

文字セットと文字エンコードがごっちゃになっているのかなと思います。 こちらが参考になるかなと思います。 http://www3.nit.ac.jp/~tamura/multimedia/japanese.html ISO-2022-JPは行頭では必ずASCIIが用いられるので、0x23 0x41 ... というバイト列が来たら、ASCII で '#' 'A' ということになるでしょうね。
LS_Takao

2021/05/20 08:01

御指摘いただきありがとうございます。 1バイトとして扱われてしまいそうだという点は理解できました。 どう改善すればよいかが判っていません。
guest

回答3

0

以下のコードで実現することが出来ました。
アドバイスをいただいた皆様、ありがとうございました。

C++

1wchar_t wcData[100]; 2memset(&wcData, 0x00, sizeof(wcData)); 3for(i=0; i<100; i++) { 4 if(0 == JIS_DATA[i]) { 5 break; 6 } 7 wcData[i] = flip16(JIS_DATA[i]); 8} 9QTextCodec *pCodec = QTextCodec::codecForName("ISO-2022-JP"); 10QByteArray aJisStr = QByteArray((const char *)&wcData[0]); 11aJisStr.insert(0, 0x1B); 12aJisStr.insert(1, 0x24); 13aJisStr.insert(2, 0x42); 14QString strWork = pCodec->toUnicode(aJisStr);

投稿2021/05/20 10:01

LS_Takao

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

文字コードが ISO-2022-JP の data.txt を Qt で扱おうとすると大体このようになります。

c++

1#include <QtCore> 2 3int main(int argc, char **argv) 4{ 5 QCoreApplication app(argc, argv); 6 7 const auto codec = QTextCodec::codecForName("ISO-2022-JP"); 8 9 QFile file("data.txt"); 10 file.open(QFile::ReadOnly); 11 const auto data = file.readAll(); 12 file.close(); 13 qDebug() << data << codec->toUnicode(data); 14 15 return 0; 16}

実行結果

shell

1"\x1B$B#A#B#C#D#E#F#G#H\x1B(B\n" "ABCDEFGH\n"

試されたコードは、ほぼ合ってそうなので、具体的になにがおかしいかの特定には
現象が再現できるような最小限のプログラム一式が必要かなと思います。

投稿2021/05/20 09:04

編集2021/05/20 09:06
tasuku.

総合スコア347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LS_Takao

2021/05/20 09:32

御回答いただきありがとうございます。 wchar_t ではなく auto を用いている点と 「#A」のようにエンディアンを逆転している点に注目して、改善策を検討してみます。
guest

0

ベストアンサー

wchar_t JIS_DATA[100];
上記の領域にJISコードの2バイト文字列(ABCDEFGH)が格納されています。

JIS X 0208 文字セットの2バイト文字がwchar_t配列に格納されているものと解釈して話を進めます。
その配列は「ISO-2022-JP で符号化されたデータ」ではないので、

QTextCodec::codecForName("ISO-2022-JP");

でデコードするのは無理です。

そこで、チカラワザになりますが、JIS_DATAの各「バイト」の最上位ビットを'1'にしてしまいましょう。
そうすればJIS_DATAを「EUC-JP でエンコードされたデータ」とみなすことが可能になるかな?と思います。

for (int i = 0; i < sizeof JIS_DATA / sizeof(wchar_t); i++) { if (0 == JIS_DATA[i]) { break; } JIS_DATA[i] |= 0x8080; } QTextCodec::codecForName("EUC-JP"); QByteArray aJisStr = QByteArray((const char *)JIS_DATA); QString strWork = pCodec->toUnicode(aJisStr);

ですかね。

全然テストしていないのでミスがあったらごめんなさい。

投稿2021/05/20 08:31

編集2021/05/20 09:19
itagagaki

総合スコア8402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LS_Takao

2021/05/20 09:10

サンプルコードを示していただきありがとうございます。 早速試してみたのですが、「ABCDEFGH」ではなく、「腺贈達庁釘藤韮硲」となってしまいました。
itagagaki

2021/05/20 09:11

バイトのエンディアンが逆かもしれないですね。
LS_Takao

2021/05/20 09:23

エンディアンを変換したところ期待通りの結果となりました。 示していただきましたコードを参考に改善策を検討致します。 貴重な時間をありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問