C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: 文字コードの取得


(過去ログ 105 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■62528 / inTopicNo.1)  文字コードの取得
  
□投稿者/ いま (1回)-(2011/10/17(Mon) 15:41:57)

分類:[C/C++] 

はじめまして。
プログラミング初心者です。
c言語を使っています。

textファイルから文字コードを取得したいのですが方法がわかりません。
ファイルOPENして,文字を読みだすのはできているのですが,
文字コードを出力する方法がわかりません。
シフトJISコードを取得したいのですが,方法はあるでしょうか?
引用返信 編集キー/
■62529 / inTopicNo.2)  Re[1]: 文字コードの取得
□投稿者/ 魔界の仮面弁士 (2392回)-(2011/10/17(Mon) 16:14:11)
No62528 (いま さん) に返信
> textファイルから文字コードを取得したいのですが方法がわかりません。
「文字コードを指定して、ファイルの内容を文字列として読み込む」ことや
「文字コードを指定して、文字列をテキストファイルとして書き込む」ことなら可能です。

しかし、ファイル(バイナリデータ)が表す文字コードを完全に判定することは無理でしょうね。
「Shift_JISデータの可能性がある」だとか、「Shift_JISである可能性が高い」とか、
「Shift_JIS または EUC-JP のどちらか」のように、推測を行うぐらいならできるかも知れませんが。


> シフトJISコードを取得したいのですが,方法はあるでしょうか?
シフトJIS の範囲外のバイナリが含まれていたら、シフトJIS ではない、と判断できます。
しかし逆に、そのファイルがシフトJISであると断定することはできません。

複数の文字コードにも解釈可能なパターンが多数ありえるからです。


"+MEIwRDBG-" という文字列は、Shift_JIS では 2B,4D,45,49,77,52,44,42,47,2D です。
  "あいう"   という文字列は、  UTF-7   では 2B,4D,45,49,77,52,44,42,47,2D です。

    "ABC"    という文字列は、Shift_JIS では 41,42,43 です。
    "ABC"    という文字列は、  UTF-8   では 41,42,43 または EF,BB,BF,41,42,43 です。

   "珎瑕"    という文字列は、Shift_JIS では E0,DD,E0,EA です。
   "珈琲"    という文字列は、  EUC-JP  では E0,DD,E0,EA です。

   "珈琲"    という文字列は、Shift_JIS では E0,DB,E0,E8 です。
   "獻琥"    という文字列は、  EUC-JP  では E0,DB,E0,E8 です。

引用返信 編集キー/
■62530 / inTopicNo.3)  Re[2]: 文字コードの取得
□投稿者/ 774RR (618回)-(2011/10/17(Mon) 16:20:07)
いや、多分そういう難しい話ではなくて SJIS で書かれているファイルがあるとき
1バイト文字を取り出す方法と
2バイト文字を取り出す方法と
がわからないだけなのかも・・・と思ったり

1バイト文字の文字コードを表示 ( 'A' に対して 41)
2バイト文字の文字コードを表示 ( あ に対して 82A0)
する方法がわからないだけなのかも・・・
引用返信 編集キー/
■62531 / inTopicNo.4)  Re[3]: 文字コードの取得
□投稿者/ いま (2回)-(2011/10/17(Mon) 16:30:49)
魔界の仮面弁士さん 774RR さん
返信ありがとうございます。

No62530 (774RR さん) に返信
> いや、多分そういう難しい話ではなくて SJIS で書かれているファイルがあるとき
> 1バイト文字を取り出す方法と
> 2バイト文字を取り出す方法と
> がわからないだけなのかも・・・と思ったり
>
> 1バイト文字の文字コードを表示 ( 'A' に対して 41)
> 2バイト文字の文字コードを表示 ( あ に対して 82A0)
> する方法がわからないだけなのかも・・・

774RRさんの言うように,1バイト文字を取り出す方法と2バイト文字を取り出す方法がわかりません。

引用返信 編集キー/
■62532 / inTopicNo.5)  Re[4]: 文字コードの取得
□投稿者/ とっちゃん (609回)-(2011/10/17(Mon) 16:55:37)
とっちゃん さんの Web サイト
No62531 (いま さん) に返信
>>1バイト文字の文字コードを表示 ( 'A' に対して 41)
>>2バイト文字の文字コードを表示 ( あ に対して 82A0)
>>する方法がわからないだけなのかも・・・
>
> 774RRさんの言うように,1バイト文字を取り出す方法と2バイト文字を取り出す方法がわかりません。
>

C言語(C++でも同様)で、特定の文字コードの判定を行う関数はコンパイラ依存だった気がします。
Visual C++(6.0以降)なら、_ismbblead で2バイト文字の1バイト目か?を判定できます。
他にもいくつかありますが、1バイト目が、0x81〜0x9F または、0xE0〜0xFC のいずれかの場合は
2バイト文字の1バイト目に当たります(_ismbb 系関数類はそれを見てさらに詳細を詰めたりしますが...)。

ただし、Shift-JISはその文字コードの利用範囲上の都合により、
先頭から順番に見ていかないと、そこが1バイト目か2バイト目かを判定することはできません。

引用返信 編集キー/
■62534 / inTopicNo.6)  Re[5]: 文字コードの取得
□投稿者/ 774RR (619回)-(2011/10/17(Mon) 17:29:59)
「ファイル」ってのは要するに「単にデータ(バイト)が順番に並んでいるだけ」の代物。
そのデータをどう解釈するかは、データを扱うユーザやプログラム任せになっている。
だから SJIS だ EUC だ UTF-8 だと、いろいろなデータ形式があるんだ。

SJIS (というか cp932) では
A という文字に 41h というコードを与えている。
あ という文字に 82a0h というコードを与えている。
そして最終的に「バイトの列」として、コードの値をそのまま配置する。
なので Aあ という文字列を「バイトの列」として取り出すと 41 82 A0 となるわけだ。

fgetc() で1バイトづつ取り出すと、最初は 41 次は 82 次は A0
fgets() で1行取り出すと、バイトデータ列の先頭は 41 次は 82 次は A0

Visual C++ では _ismbblead() という関数に 41 を食わせると 0 が返ってくる
すなわち multi byte lead 文字でない = 1バイトが半角1文字分である = 41 で1文字
同様 _ismbblead() に 82 を食わせると 0以外 が返ってくる。
すなわち multi byte lead 文字である = 後続のバイトとあわせて1文字である =
(SJIS の場合) 82 と次の A0 をあわせて 82A0 で1文字である
と判断すればいいんだ。

# UTF-8 などの場合「後続のバイト」が1バイトとは限らないので注意が必要。
# cp932 (SJIS) は1バイトか2バイトかのどちらかなので簡単。

SJIS はバイト列の途中から1バイト目か2バイト目かを判断できない(こともないが困難)ので
先頭からチェックしていかなければならない。その辺注意が必要。
引用返信 編集キー/
■62536 / inTopicNo.7)  Re[6]: 文字コードの取得
□投稿者/ 魔界の仮面弁士 (2393回)-(2011/10/17(Mon) 19:04:18)
No62534 (774RR さん) に返信
> # UTF-8 などの場合「後続のバイト」が1バイトとは限らないので注意が必要。
> # cp932 (SJIS) は1バイトか2バイトかのどちらかなので簡単。
> SJIS はバイト列の途中から1バイト目か2バイト目かを判断できない(こともないが困難)ので
> 先頭からチェックしていかなければならない。その辺注意が必要。

具体例を挙げてみると…たとえば cp932 の場合
 「=」 … 81,81
 「≠」 … 81,82
 「a」 … 82,81
 「b」 … 82,82
のように、先導バイトにも後続バイトにもなりうるバイナリ値が存在するため、
常に文字列の先頭から調べていく必要があるということになります。

一方、UTF-8 の場合は、
 1バイト文字:0xxxxxxx
 2バイト文字:110xxxxx 10yyyyyy
 3バイト文字:1110xxxx 10yyyyyy 10zzzzzz
 4バイト文字:11110www 10xxxxxx 10yyyyyy 10zzzzzz
というビットパターンになるため、データの途中からでも文字列の区切りを見つけることができます。
1バイトなら[00-7F]、2バイト文字は[C2-DF],[80-BF]、3バイト文字は[E0-EF],[80-BF],[80-BF]であり、
後続のデータを何バイト読み込めば良いのかは、先頭バイトで判断することができます。

引用返信 編集キー/
■62557 / inTopicNo.8)  Re[7]: 文字コードの取得
□投稿者/ PATIO (127回)-(2011/10/18(Tue) 13:25:07)
2011/10/18(Tue) 13:26:20 編集(投稿者)
2011/10/18(Tue) 13:25:35 編集(投稿者)

文字コードの話は既に皆さんが書かれていますし、
ファイルに関しても書かれている方がいますので少し違った話を。

プログラミングと言うとどうしてもプログラミング言語の方に話が行ってしまいがちですけれど、
プログラミングをする為には情報処理の基本的な知識と言うのは結構要求されます。
プログラミング言語の入門書ならこの辺の内容まで触れているものもあると思いますけれど、
言語の勉強にだけ傾いてしまうと単にソースコード上の記述だけに目が行ってしまうので出来れば、
今回話に挙がっているような
ファイルってどんなものなのか?
テキストファイルって?
文字列と文字コードの関係は?
メモリ上に読み込んだときどんな風になっているの?
と言った部分まで理解できるように勉強してみると良いと思います。

で、この辺がイメージできるようになるとプログラミングの時に
どういうコードを書けば処理できるのかと言う部分を考える助けになります。
逆にイメージできない状態でコードを書いても多分内容が理解できないです。
書かれたコードが具体的に何をやっているのかと言うは大切なので
コードを書く事だけに傾倒しないでコードを理解する事を大事にしてください。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -