日本語(漢字含む)が書かれたファイルから、データを配列に収めるにはどうしたらいいのでしょうか?(長々とかかれていますがこれが主題です。後は読まずにこの文章に対してだけ答えてくださっても結構です。)
◆fgetc()で1文字ずつchar型の配列に収めていったのですが、その配列の内容を表示してみると、カタカナと「、」からなる意味不明の文字列が表示されてしまいました。表示は、%sで表示する方法と、%cで1文字ずつをループをつかって表示する方法の2通りの方法を試してみましたが、どっちもダメでした。なぜなんでしょうか???(ちなみに英字ならうまくいくのですが…)
ない頭を使って考えてみたんですが、漢字のバイト数を2バイトと仮定すると、(そうではないものもあるらしいのですが…)char型の配列の要素1個あたり1バイトなので、要素1個には、漢字の情報の半分の情報量しか含まれていないからではないか、とおもったんですが、どうでしょうか?
◆しかし、fgetc()ではなく、fgets()で収めてみると、なぜかうまく表示されます(この場合、1行分だけですが)。前出の2つの方法の両方で。なぜなのでしょうか??????????
じゃあ、その方法でヤレバいいじゃん、といわれそうですがしかし、fgets()だと1行分配列に収めた後、さらに同じ配列にデータの続きを収めることができないからです。つまり、ファイルから1行分しか配列に収められないと…まぁ、何か方法はあると思いますが、いずれにしろスマートではなくなるのでは、と思うのです。
長くなってしまって、ごめんなさい。文章が下手で…(汗汗)
どこか1部分に対する回答や、アドバイスでも結構ですので、よろしくお願いします。
No.5ベストアンサー
- 回答日時:
>…あっ、そうか!このdata[0]に格納されている2進数値列を%cで出力しようとしても、対応するcharacterが無いから何も表示されない、というコトなんですかね???
そういう考えでだいたいいいと思います。
正確には,漢字の半分のデータしかないので
何を出していいか分からない状態なので、
何も出ないという状態だと思います。
3byteの方も同様です。
例えば,「亜」をShift JISで表示するためには,
0x88 0x9fを送る必要がありますが、空白がはいると
0x88 0x20 0x9fが送られます。
0x88 0x20が漢字と解釈されますが、該当する文字は
ありませんので、多分空白となるでしょう。
0x9fは半分なので表示できない・・となると思います。
ただ、こういう未定義のコードを出した場合どうなるかは、
場合によって違うかも知れません。
未定義ですから。
ありがとうございました。
ぼくの持っているCの本は、日本語についてあまり言及していないので全然解らなかったのです。(英字は1バイト。日本語は2バイトなんだけどね、くらいの説明)
今回、いろいろとわかってよかったです。ありがとうございました。
No.4
- 回答日時:
>printf("%c",data[0]);でも、
1byteしか出力されません。
>printf("%c %c",data[0],data[1]);でも何も表示されないのに、
' 'が2番目に出力されるので、3byte出力されます。
>printf("%c%c",data[0],data[1]);
2byte出力されます。
というわけで、同じ物が出ていないので結果が違うわけです。
これは元の配列が,intでもcharでも同じことです。
>日本語1文字につき、何が何でも2つの変数に入れなくてはならないのでしょうか?
そんなことはありませんが、その方が説明も楽です(^^;
例えば,long intが4byteならShift JISなら二文字入れることが可能ですが,
いろいろと環境に依存する問題も出てきそうなので,
面倒なので避けます(^^;;;
この回答への補足
回答ありがとうございました。
>' 'が2番目に出力されるので、3byte出力されます。
あ、そうか…スペースの存在を忘れていました。でもこの場合、
スペースしか表示されないんですよね。文字が何もでてこない…
>>printf("%c",data[0]);でも、
>1byteしか出力されません。
ここなんです。1byte出力されるはずなのに何も表示されないのです…
…あっ、そうか!このdata[0]に格納されている2進数値列を%cで出力しようとしても、対応するcharacterが無いから何も表示されない、というコトなんですかね???
No.3
- 回答日時:
こんにちは。
itohhといいます。記憶があいまいなのですが、
fgetc関数は、2バイト文字の場合、1バイト落としてしまいます。
それなので、文字化けしたようになります。
fopen関数をバイナリモードでオープンするといいかもしれません。
すみません、試していないので間違っているかもしれません。
fread関数でEOFになるまで読み込んでいくのは如何ですか?
例えば、
FILE *stream;
char wRec[100];
char wBuf[1024];
int wCnt, numread;
/* バイナリモードでファイルを開く */
if( (stream = fopen( "fread.out", "r+b" )) != NULL )
{
wCnt = 0;
memset( wBuf, 0x00, sizeof(wBuf) );
/* EOFになるまで読み込む */
while( !feof( stream ) )
{
numread = fread( wRec, sizeof( char ), 100, stream );
memcpy( &wBuf[wCnt], wRec, numread );
wCnt += numread;
}
fclose( stream );
}
本来は、wBufは、ファイルのサイズを調査してファイルサイズ+1バイトのエリアを
malloc関数で確保するべきだと思います。
det_mul2さんの環境がUNIXなのかWindowsなのか解らないのでファイルサイズを取得す
る関数は省略しました。
また、エラー処理も省略していますので、それなりに行ってください。
ファイルサイズが解るのならば、
while文でループしないで
numread = fread( wBuf, sizeof( char ), ファイルサイズ, stream );
でもOKです。
アドバイスありがとうございました。
昨日あきらめて、今日起きてちょっといじったら、うまくいきました。
小さなところを間違えていたようです…お騒がせしてすみませんでした。
それにしても、まだ解らないことがタックサンです。
日本語データを、char型の配列data[]にいれたとすると、
printf("%c",data[0]);でも、
printf("%c %c",data[0],data[1]);でも何も表示されないのに、
printf("%c%c",data[0],data[1]);ならちゃんと日本語が1文字表示されちゃうんですよね~2バイト文字を表示するには連続して表示しなければいけないというルールがあるのかな…???
int型の配列idata[]に同じデータを入れてみても、
printf("%c",idata[0]);でも、
printf("%c %c",idata[0],idata[1]);でも何も表示されないのに、
printf("%c%c",idata[0],idata[1]);ならちゃんと日本語が1文字表示されちゃうんですよね~。int型は2バイト以上あるはずなのに、、、
日本語1文字につき、何が何でも2つの変数に入れなくてはならないのでしょうか?
>fopen関数をバイナリモードでオープンするといいかもしれません。
おっと、そんな別な方法もあるのですか。これは知りませんでした。まだまだ勉強が足りません。はやく、もっと自由自在にプログラミングができるようになりたいな~(独り言でした)
No.2
- 回答日時:
この手の問題は処理系,環境,コンパイラ,実際のプログラムが無いと判断が難しいです。
自分で問題だと判断したところでなく,なるべく全体を、
何をしたいかを書いたほうがいいですよ。
全く関係の無いと思っていたところが,問題な場合もありますし。
fgetcで失敗するのは,プログラムに問題(バグ)があるような気がしますが,実際のソースコードがないと判断つきません。
アドバイスありがとうございました。
昨日あきらめて、今日起きてちょっといじったら、うまくいきました。
小さなところを間違えていたようです…お騒がせしてすみませんでした。
それにしても、まだ解らないことがタックサンです。
日本語データを、char型の配列data[]にいれたとすると、
printf("%c",data[0]);でも、
printf("%c %c",data[0],data[1]);でも何も表示されないのに、
printf("%c%c",data[0],data[1]);ならちゃんと日本語が1文字表示されちゃうんですよね~2バイト文字を表示するには連続して表示しなければいけないというルールがあるのかな…???
int型の配列idata[]に同じデータを入れてみても、
printf("%c",idata[0]);でも、
printf("%c %c",idata[0],idata[1]);でも何も表示されないのに、
printf("%c%c",idata[0],idata[1]);ならちゃんと日本語が1文字表示されちゃうんですよね~。int型は2バイト以上あるはずなのに、、、
日本語1文字につき、何が何でも2つの変数に入れなくてはならないのでしょうか?
No.1
- 回答日時:
解決方法がわからないのでアドバイスです。
すいません。fgetc() だとだめで、fgets() ならうまくいくということは、
配列の中身も違うのではないでしょうか?
while(*s){
printf("%02X ", *s);
s++;
}
とかで、配列の中身を確認してみてはいかがでしょう?
2つの違いで何かわかるかもしれないですよ。
アドバイスありがとうございました。
昨日あきらめて、今日起きてちょっといじったら、うまくいきました。
小さなところを間違えていたようです…お騒がせしてすみませんでした。
それにしても、まだ解らないことがタックサンです。
日本語データを、char型の配列data[]にいれたとすると、
printf("%c",data[0]);でも、
printf("%c %c",data[0],data[1]);でも何も表示されないのに、
printf("%c%c",data[0],data[1]);ならちゃんと日本語が1文字表示されちゃうんですよね~2バイト文字を表示するには連続して表示しなければいけないというルールがあるのかな…???
int型の配列idata[]に同じデータを入れてみても、
printf("%c",idata[0]);でも、
printf("%c %c",idata[0],idata[1]);でも何も表示されないのに、
printf("%c%c",idata[0],idata[1]);ならちゃんと日本語が1文字表示されちゃうんですよね~。int型は2バイト以上あるはずなのに、、、
日本語1文字につき、何が何でも2つの変数に入れなくてはならないのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- Visual Basic(VBA) VBA 「,」・空白・カタカナ等の複数条件のマクロ 2 2023/08/23 11:57
- SQL Server [SQLServer] テーブル名からカラム名を取得する 1 2022/08/23 21:20
- Excel(エクセル) エクセルの数式で教えてください。 1 2023/02/15 08:30
- C言語・C++・C# C言語の質問です。 以下の命令を実行するプログラムを作りました ①文字列aとbの長さを表示 ②aとb 1 2022/04/29 15:35
- Excel(エクセル) Excelでの検索結果を含む行だけを表示させたい 5 2023/03/10 17:08
- Excel(エクセル) PowerQueryに詳しい方教えてください(Office365) 1 2022/07/24 21:11
- Excel(エクセル) Excelの関数についておしえてください。 3 2023/04/20 18:36
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- Visual Basic(VBA) Excel VBA 書式変更で困ってます。 オートフィルターの日付フィルターを用いて データの絞り込 2 2022/07/26 22:16
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 配列の長さの上限
-
配列を使わずに、変数名を動的...
-
RGB値を画像(PNG・BMPJPEGなど)...
-
パイソンの
-
テキストファイルから文字列を...
-
C# 配列の変数宣言について。
-
先頭アドレスとは何ですか?
-
複数の選択範囲の行番号を個別...
-
配列の参照渡しで型が一致しま...
-
C言語で巨大配列を作るにはどう...
-
配列を含む構造体の初期値について
-
C言語で特定列だけを抽出して配...
-
C言語 変換指定%sについてです。
-
【C言語】配列の中に配列を入れ...
-
unsigned char配列への入力の仕方
-
配列で格納したものをmsgboxで...
-
構造体配列を引数とするDLL作成...
-
vectorで文字列の配列を使う方法
-
Redimした動的配列はEraseする...
-
市販のビンゴカードについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 配列の長さの上限
-
配列の参照渡しで型が一致しま...
-
配列を使わずに、変数名を動的...
-
VBで構造体の配列を関数に渡す...
-
配列で格納したものをmsgboxで...
-
unsigned char配列への入力の仕方
-
C# Listを使わずに2次元配列の...
-
C# 配列の変数宣言について。
-
擬似コード 長さがmの配列でな...
-
【速いブラインドタッチ】手を...
-
パイソンの
-
C言語初心者 ポインタについて...
-
ExcelVBAで質問です。離れた二...
-
配列を含む構造体の初期値について
-
複数の選択範囲の行番号を個別...
-
Functionの戻り値を2次元配列...
-
C++ vectorに配列をプッシュしたい
-
先頭アドレスとは何ですか?
-
テキストファイルから文字列を...
-
Redimした動的配列はEraseする...
おすすめ情報