No.9ベストアンサー
- 回答日時:
うーん。
それはC言語の基礎ですがC言語は文字列の終端に0をいれます。
buffer[wReadSize/sizeof(wchar_t)] = 0;
と同じことですか。
明示的にUNICODEのNULL文字 L'\0'としています。
別に文字列として扱わないなら必要ありません。
しかし今回は
MessageBox関数に使用する為、bufferを文字列として扱う必要がある為
NULL文字をいれました。
mallocでwReadSize + sizeof(wchar_t) としているのも
NULL文字をいれるため文字数+1文字しているのです。
どんな言語でもそうですが、文字列を扱うには2通りの方法があって
今回のように文字列の終端に終端を表すNULL文字をいれる仕組みと
最初に文字数があってその後ろに文字列がくる仕組みです。
でなければコンピューターはどこまでが文字列なのか判断出来ません。
>この部分ってUNICODEファイルを読むときで必ず必要でしょうか?
>保険のようものでしょうか?
つまりUNICODEかどうかは関係ありませんし保険でも無く
文字列として扱うなら必ず必要ということです。
ありがとうございました。
大変勉強になりました。
文字列の終端のことで気になったのは今回おそらく私のどっかのミスで余計な文字が
読み込まれたので、それをきるために、そのようにされたのかなと思いましたので
質問させていただきました。
解説ですっきりしました。
.NETから入ってnative系の戻るってともてつらいです。。。
.NETが基本的なところ全部やってくれますので。。。スキルが上がりませんね。
これから出てくるPGならもっと不幸かもしれません(ある意味でです)。
#私は.NETが優れていると思います。
No.8
- 回答日時:
HANDLE hFile = CreateFile( "text.txt", GENERIC_READ , 0 , NULL ,
OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL);
DWORD wReadSize = GetFileSize(hFile , NULL);
wchar_t* buffer = (wchar_t*)malloc( wReadSize + sizeof(wchar_t) );
DWORD dw;
ReadFile( hFile , buffer , wReadSize , &dw , NULL );
buffer[wReadSize/sizeof(wchar_t)] = L'\0';
::MessageBox( NULL , buffer , L"test" , MB_OK );
free(buffer);
CloseHandle(hFile);
そのまま回答書いてくださいましたね<(_ _)>
ファイル読めてますね。ありがとうございます。
> buffer[wReadSize/sizeof(wchar_t)] = L'\0';
この部分ってUNICODEファイルを読むときで必ず必要でしょうか?
ほかのコードのファイルでも必要?
それとも、余計なものを確保される可能があるので、保険のようものでしょうか?
No.7
- 回答日時:
開いているファイルのバイト数はいくつでしょうか。
可能であれば、ファイル内の各バイトの値も教えてください。プログラム内で使用している各変数に最終的に設定されている値と、ファイルを読み込んだ後のバッファ内の値はいくつでしょうか。(ハンドルの値、ポインタの値は不要です。)
この回答への補足
メモ帳でUNIOCDE保存したファイル
サイズ 6 バイト
内容 aあ
wReadSize 3
dw 6
です。
なにおわかりでしょうか?
すいません。
補足がもうできませんので、お礼のとこで^^
やっているうちに漢字が取れました。
ありがとうございます。
依然として余計な文字が読み込まれますが。。
各値も漏れてましたね。
aあ 以外の化けている値は以下です。
65021
65021
43947
43947
43947
43947
65262
もしかして、UNICODEの制御文字?
文字コードが理解できてません。。。
No.6
- 回答日時:
回答No.5の補足にあるコードですが、GetFileSizeが返す値は「バイト数」で、Unicode文字の文字数ではありません。
ですので、Unicode文字の文字数を得るにはsizeof(wchat_t)で割ってください。(注:ヘッダ込みの値になります。)この回答への補足
ご回答ありがとうございます。
なんとなくそんな気もしましたので、
テストとして固定で 2 を入れてもやってみたのです。
なんか、とくに結果がかわりませんで、そのまま
ほうっておきました。
おっしゃる通りですね。
それでも結果が変わらないのはなんででしょうか。。?
それと、余計な文字を読み込み以外にポインタ移動や
配列のインデックス指定で漢字が取れません。。
根本的に間違ってますでしょうか?
No.5
- 回答日時:
何を悩んでいるのかわかりませんが、
例えばテキスト文書が1000文字なら
wchar_t buffer[1000];
とでも用意してください。
(wchar_tはワイド文字の型です。U
NICODEを宣言しているならTCHARでも同じです。)
BOOL ReadFile(
HANDLE hFile, // ファイルのハンドル
LPVOID lpBuffer, // データバッファ
DWORD nNumberOfBytesToRead, // 読み取り対象のバイト数
LPDWORD lpNumberOfBytesRead, // 読み取ったバイト数
LPOVERLAPPED lpOverlapped // オーバーラップ構造体のバッファ
);
がReadFileの定義ですが
DWORD dw;
ReadFile( hFile , buffer , sizeof(wchar_t) * 1000 , &dw , NULL );
これで
buffer[1]・・・あ
buffer[2]・・・a
buffer[3]・・・b
buffer[4]・・・い
buffer[5]・・・c
・
・
・
とはいっているはずです。
ところでUNICODE-UCS2は全ては2バイトです。ですから半角とか全角とかは関係ありません。
まずメモ帳等でUNICODE形式を保存すればわかりますがテキストファイル
の最初にFF FE またはFE FFがつきます。これはLittleEndianかBigEndianの指標で
Windowsの標準はlittle endianです。
それを考慮してbuffer[0]からではなくbuffer[1]からにしています。
この回答への補足
以下のようにやってみましたが、やはりできません^^;
ステップ実行すると、確かにbufferに読み込まれるんですが、
最後に意味不明の文字が入ってしまいます。
ファイルはメモ帳でUNICODEで保存しました。
aあ
の2文字が入ってます。
bufferの値は正確に再現できません。化けてますので、おそらく投稿するとさらに違う変な文字になったりしてます。
bufferのポインタを移動するとやはり全角の文字は取れません。。
配列でもやってみましたが、同じ結果でした。
すいません。どんなところがおかしいでしょうか?
きっとおかしいでしょうが、発見できませんです。。。
HANDLE hFile = CreateFile( ファイル名, GENERIC_READ , 0 , NULL ,
OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL);
DWORD wReadSize = GetFileSize(hFile , NULL);
wchar_t* buffer = (wchar_t*)malloc( sizeof(wchar_t) * wReadSize );
DWORD dw;
ReadFile( hFile , buffer , sizeof(wchar_t) * wReadSize , &dw , NULL );
free(buffer);
CloseHandle(hFile);
ご回答ありがとうございます。
> ところでUNICODE-UCS2は全ては2バイトです。ですから半角とか全角とかは関係ありません。
全くおっしゃる通りです。
私のそのように考えていました。
.NETではそのようになってますし。
しかしいざCでやってみるとあれ?なんか。。
え?うん~。。って感じでどうにもできませんでした^^;
今からもう一度やってみます。
また結果を報告いたします。
No.4
- 回答日時:
読み込むファイルのエンコードはShift-JIS、UCS-2(いわゆるユニコード)、UTF-8、UTF-16のどれでしょうか。
参考:
http://www.atmarkit.co.jp/fxml/askxmlexpert/024u …
(マイクロソフトのCコンパイラを使うものと仮定します。)
Shift-JISの場合、2バイト文字の1バイト目であるかどうかは_ismbblead()関数で判定できます。_istlead()は_UNICODEが定義されている場合常にfalseを返すので、今回の場合おそらく使用できません。(_MBCSが定義されている場合_ismbblead()を返します。)
UCS-2(ユニコード)の場合、全角文字でも半角文字でも常に2バイトですから、1バイト目であるかどうかの判定は必要ありません。
UTF-8/16はよく知らないので省略します。
No.3
- 回答日時:
#2です。
例で書いたソースはあくまでもバイトごとに読み込むサンプルとして挙げただけですので、あとはご自分で作ってもらえればと思ったのですが・・・
とりあえずUnicodeの細かい処理は省いて(良くわからないので)1文字=4バイトとした場合のソースを書いておきます。
単純に文字で表示させます。
for( i = 0; i < len; i+=4 ){
printf( "%.4s\n", &p[i] );
}
一旦バッファに取り込むなら。
char w[5];
for( i = 0; i < len; i+=4 ){
strncpy( w, &p[i], 4 );
printf( "%s\n", w );
}
こんなんでよろしいでしょうか?
的外れなら補足お願いします。
この回答への補足
へんな質問ですいません。
全角、半角が混ざっているファイルですので、
forのループごとに同じ量の移動ができないです。
全角かどうかの判定がしたいですが、
ソース内部でUNICODEを#defineしているため
_istleadでしたっけ?が使えないようです。
どんな方法でもいいですが、
あabいc
のような文字の場合
あ
a
b
い
c
と取り出したいだけです。
No.2
- 回答日時:
例えば char* p に読み込んだとしたら、p[0] が0バイト目のデータです。
全データを16進で表示するサンプルを書いておきます。
len は ReadFile の4番目の引数の値(読み込んだバイト数)と思ってください。
例:
for( i = 0; i < len; i++ ){
printf( "%02x\n", p[i] );
}
もしくはポインタを使うならこうなります。
for( i = 0; i < len; i++, p++ ){
printf( "%02x\n", *p );
}
ご回答ありがとうございます。
すいませんです。いい忘れました。
全角、半角は混ざったファイルで
読み込んだ内容を"文字"として一つずと取り出すには
どうしたらいいでしょうか。書いていただいたサンプルがもしすでにそうなっていれば
もうすこし解説をいただけないでしょうか?
どうしても、一バイトずつ表示しているように見えてしまいます。
これでは2バイト文字は。。。?
すいません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
10Mバイトて文字数に すると何...
-
char str[256]の256の意味は?
-
文字コードの利点、欠点
-
「1TB」のHDDに日本語は何字入...
-
【VB2005】テキストボックス内...
-
VBAでShift-JISのURLエンコード
-
ピクセル,dpiから容量(バイト...
-
pythonでバイナリデータを配列...
-
文字数の限界
-
CRC計算方法
-
固定文字のみ【文字化け】
-
memcmp バイナリデータの比較方法
-
UTF-8で5~6バイトになる文字コ...
-
VB6で漢字の1バイト目か2バイト...
-
エクセルシート名の制限を変更...
-
ビットスワップとバイトスワッ...
-
formからPOSTしたテキストエリ...
-
バイナリデータからの値の取得...
-
utf-8でメールを送信すると件名...
-
C言語でのLinuxとwindows共通の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルシート名の制限を変更...
-
UTF-8で5~6バイトになる文字コ...
-
10Mバイトて文字数に すると何...
-
COBOLのCOMP形式について
-
char str[256]の256の意味は?
-
バイト列とバイナリ列の違いが...
-
ピクセル,dpiから容量(バイト...
-
「1TB」のHDDに日本語は何字入...
-
Javaで日本語1文字のバイト数
-
機種依存文字をチェックしたい。
-
PICマイコンで変数値の保持
-
【VB2005】テキストボックス内...
-
SQLで1バイト、2バイト混在...
-
ビットスワップとバイトスワッ...
-
VBAでShift-JISのURLエンコード
-
GetWindowTextでアドレスバーか...
-
C++ Builderで文字列をバイトに...
-
64bit対応
-
UCS-2の一覧表が欲しい
-
VB.NET LeftBの代用
おすすめ情報