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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

4344閲覧

バイナリデータから読み取った文字が文字化けしてしまう場合の対処法が知りたい。プログラム上で文字コードを変更する方法?

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2021/01/18 06:55

編集2021/01/18 08:35

提示コードの下部のコメント部ですが// #### で囲ってあるコードですが。文字化けしている出力結果ですが文字化けしている部分はバイナリデータでいうIARTの内容なのです文字化けしていします。バイナリエディタではutf-8に文字コードを変更したのですがプログラム上ではどうすればいいのでしょうか?

試したこと。
wchar_t型に入れて画面に表示

イメージ説明
イメージ説明

cpp

1#include "stdio.h" 2#include "Windows.h" 3#include "OpenAL/include/al.h" 4#include "OpenAL/include/alc.h" 5 6#define HEADER_SIZE ((int)44) 7 8const char* tag[8][4]{{"IART"},{"INAM"},{"IPRD"},{"IGNR"},{"INAM"},{"ICMT"},{"ICRD"},{"ISFT"}}; 9 10// タグを探す 11const char* searchTag(unsigned char* header,const char* tag) 12{ 13 const char* str = strstr((const char*)header, (const char*)tag); 14 15 return str; 16} 17 18// 19void printf_subChunk(unsigned char* header,int size) 20{ 21 22} 23 24// フォーマットを取得 25ALenum getFormat(int wavChannels, int wavBit) 26{ 27 ALenum format = 0; 28 if (wavChannels == 1) { 29 if (wavBit == 8) { 30 format = AL_FORMAT_MONO8; 31 } 32 else if (wavBit == 16) { 33 format = AL_FORMAT_MONO16; 34 } 35 } 36 else if (wavChannels == 2) { 37 if (wavBit == 8) { 38 format = AL_FORMAT_STEREO8; 39 } 40 else if (wavBit == 16) { 41 format = AL_FORMAT_STEREO16; 42 } 43 } 44 return format; 45} 46 47// ########## チャンクデータ 48struct Chunk_Data { 49 50public: 51 52 char riff[5]; // "RIFF" 53 int chunk_size; //チャンクのサイズ 54 int format; //フォーマット 55 ALenum alenumFormat; //alenumフォーマット 56 char fmt[5]; // "fmt" 57 int fmt_chunk_byte; //fmtチャンクのバイト数 58 short sound_format; //音フォーマット 59 short channel; //チャンネル数 60 int sample_rate; //サンプリング周波数 61 int byte_per_sec; //1秒あたりのバイトの平均 62 short block_size; //ブロックサイズ 63 short bit_per_sample; //1サンプルに必要なビット数 64 65 short extension_size; //拡張パラメーター サイズ 66 unsigned char* extension_data = nullptr; //拡張パラメーター 67 68 char sub_chunck[5]; // サブチャンクID 69 int sub_chunck_size; // サブチャンク サイズ 70 long long int DataSize; //波形データのバイト数 71 int all_DataSize; //ファイル全体のサイズ 72 int playTime; 73 74 75 unsigned char* Data = nullptr; //音データ 76}; 77 78 79// バイナリを各型に変換 80int convInt(unsigned char* header, int start) 81{ 82 int ret = (header[start + 3] << 24) | (header[start + 2] << 16) | (header[start + 1] << 8) | (header[start + 0]); 83 84 return ret; 85} 86 87short convShort(unsigned char* header, int start) 88{ 89 int ret = (header[start + 1] << 8) | (header[start + 0]); 90 return ret; 91} 92 93char convChar(unsigned char* header, int start) 94{ 95 char ret = header[start]; 96 return ret; 97} 98 99 100 101// 文字列を返す 102bool convStr(unsigned char* header, char* str,int str_size,int start,int n) 103{ 104 int r = n - start;// コピー文字数 105 106 if (str_size > r) { 107 return false; 108 } 109 110 for (int i = 0; i < r; i++) 111 { 112 str[i] = header[start + i]; 113 } 114 115 return true; 116} 117 118 119int main() 120{ 121 122 const char* file = "sample2.wav"; //ファイル名指定 123// const char* file = "sample.wav"; //ファイル名指定 124 FILE* fp = NULL; //ファイルポインタ 125 126 struct Chunk_Data chunk; 127 128 129 ALuint source; 130 ALuint buffer; 131 132 // デバイスを開く 133 ALCdevice* device = alcOpenDevice(NULL); 134 if (!device) 135 { 136 printf("デバイスを作成出来ません。\n"); 137 } 138 139 ALCcontext* context = alcCreateContext(device, NULL); 140 if (!context) 141 { 142 printf("コンテキストを作成出来ません。\n"); 143 } 144 145 alcMakeContextCurrent(context); // コンテキストを適用 146 147 alGenSources(1, &source); // 148 alGenBuffers(1, &buffer); // 149 150 //ファイルを開く 151 fopen_s(&fp, file, "rb"); 152 if (!fp) { 153 printf("ファイルが開けません。\n"); 154 } 155 156 unsigned char* Data;//音データーのサイズ 157 unsigned char header[HEADER_SIZE] = { 0 }; //ヘッダーサイズ 158 159 fread(header, 1, (size_t)HEADER_SIZE, fp); //チャンクデータを読み込む 160 chunk.DataSize = convInt(header, 40); //波形データのサイズ 161 chunk.all_DataSize = chunk.DataSize + 40; //ファイル全体のサイズ 162 163// ################################################################################################ 164 165 char str[10] = { '\0' }; 166 char str2[70] = { '\0' }; 167 char str3[70] = { '\0' }; 168 169 170 if (convStr(header, str, strlen(str), 0, 4) == false) { printf("失敗str\n"); }; 171 printf("RIFF ID: %s\n", str); 172 173 // 174 int r = convInt(header,4); 175 printf("サイズ: %d\n", r + 8); 176 177 // 178 if (convStr(header, str2, strlen(str2), 8,12 ) == false) { printf("失敗str2\n"); }; 179 printf("フォームタイプ %s\n", str2); 180 181 //LIST 182 if (convStr(header, str3, strlen(str3), 36, 40) == false) { printf("失敗str3\n"); }; 183 printf("サブチャンク ID %s\n", str3); 184 185 int size = convInt(header, 40); 186 printf("サブチャンクサイズ: %d\n", size); 187 188 unsigned char* list = new unsigned char[size] { '\0' }; 189 190 fread(list, 1, (size_t)size + 40,fp); 191 char str4[40]{ '\0' }; 192 if (convStr(list, str4, strlen(str4), 0, 4) == false) { printf("失敗str4\n"); }; 193 printf(": %s\n", str4); 194 195 char str5[50]= { '\0' }; 196 if (convStr(list, str5, strlen(str5), 4, 8) == false) { printf("失敗str4\n"); }; 197 printf(": %s\n", str5); 198 199 int a = convInt(list,8); 200 printf("%d\n", a); 201 char st[200]; 202 203 // ################################################### 204 strncpy_s(st,(char*)list + 12, (size_t)12 + a); 205 //printf("%c", st[0]); 206 printf("%s",st); 207 // ################################################### 208 209 210 211 212 213// ################################################################################################ 214 chunk.alenumFormat = getFormat(chunk.channel, chunk.bit_per_sample); 215 chunk.Data = new unsigned char[chunk.DataSize]{ 0 }; // 音データを作る 216 fread(chunk.Data, 1, chunk.DataSize, fp); 217 alBufferData(buffer, chunk.alenumFormat, chunk.Data, chunk.DataSize, chunk.sample_rate); 218 alSourcei(source, AL_BUFFER, buffer); 219 alSourcePlay(source); 220 221 222// Sleep(time * 1000); 223 224 225 return 0; 226}

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

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

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

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

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

guest

回答1

0

ベストアンサー

UTF-8 を WCHAR に変換して表示しましょう。

Windowsであれば、MultiByteToWideChar(CP_UTF8, ...)WCHAR に変換し、書式指定子 %lsWCHAR 文字列をコンソールに表示します。

C標準のmbstowcs()はプロセス全体のロケールをUTF-8に変更する必要があるのでこのケースでは使えないと思います。

MultiByteToWideChar()
書式指定構文: printf 関数と wprintf 関数

投稿2021/01/19 00:59

int32_t

総合スコア20884

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

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

退会済みユーザー

退会済みユーザー

2021/01/19 01:48 編集

まあ、WAVEのLISTチャンクって文字コードの規定がないので、シフトJISで入ってたら化けるんですけどね。ソフトによって対応がまちまちです。 http://reika788.blog.fc2.com/blog-entry-6.html 国際対応用のCSETというチャンクも存在するらしいですが、実装しているソフトを見た事が無い…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問