バイナリデータ読み込み

[戻る]
ピースケ 2006/07/19(水) 15:33:21
環境 VC++ 6.0
OS windowsxp
ダイアログベースでクラスの新規作成 Genericクラス

お世話になります。

36 36 41 35 4C 31 30 30-2D 30 30 36 4B 00 48 2E
4B 41 53 48 4  4D 41 00-00 00 33 20 33 20 4D 35
・・・・・・

とゆうようなバイナリーデータを頭から2バイト,12バイト,12バイト,2バイト・・・
と変数に格納するプログラムを書いています(全部で256バイト)。

ファイルを開く事はCreateFileを使ってるのですが
読込みや変数への格納がいまいち分りません。
またreadfile はデータすべてを読み込んでくれるものと理解しています
(この場合は256全部読み込む)が合ってますか?
http://72.14.203.104/search?
q=cache:EiZXrCRUERAJ:www.microsoft.com/japan/developer/library/jpwinpf/_win32_r
eadfile.htm+ReadFile()&hl=ja&gl=jp&ct=clnk&cd=1&lr=lang_ja

どなたか分る方がいましたらよろしくお願い致します。


HANDLE  hf
LPSTR   strFile      // 入力データを格納する領域を指定します
DWORD  dwResult;  // 読み取ったバッファ
long    m_lAaa      // 最初の2バイト
CString m_szBbb     //  次の12バイト    
CString m_szCcc   //  次の12バイト    
CString m_szDdd   // 次の12バイト    


hF = CreateFile
(FilePath,ENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if (hF == INVALID_HANDLE_VALUE)
{
 return FALSE ;
}
 ReadFile(hF, strFile, GetFileSize(hFile , NULL), &dwResult, NULL);

//これ以降の処理で先頭2バイトを m_lAaa ・・・に格納する方法が不明

ピースケ 2006/07/19(水) 15:35:13
申し訳ありません

間違えてしまい二重送信してしまいました。

επιστημη 2006/07/19(水) 15:48:08
> 読込みや変数への格納がいまいち分りません。

「いまいち分かりません」の一言ではなにがどう分からんのかさっぱり分かりません。

επιστημη 2006/07/19(水) 15:55:07
> とゆうようなバイナリーデータを頭から2バイト,12バイト,12バイト,2バイト・・・
> と変数に格納するプログラムを書いています(全部で256バイト)。

2 + 12x21 = 254 … 2バイト余ります。

tetrapod 2006/07/19(水) 16:16:02
256 / (2+12+12) = 9 ... 22 かもしれないが、いずれにせよあまることは同じ。

あまりにもツッコミどころが多すぎるのですが、基礎は大丈夫?

strFile はどこ指してる?
ReadFile 1回呼ぶだけでファイル全部読まれたらたまらないよ。
CString にバイナリ入れることはできないよ。

tetrapod 2006/07/19(水) 16:21:18
ああ GetFileSize してるのか... でもどのみちファイル名間違って指定されると
とんでもないことになりそうな気のせい?

三草 2006/07/19(水) 16:21:27
MSDNより。。。

-------------------------

BOOL ReadFile(
  HANDLE hFile,                // ファイルのハンドル
  LPVOID lpBuffer,             // データバッファ
  DWORD nNumberOfBytesToRead,  // 読み取り対象のバイト数
  LPDWORD lpNumberOfBytesRead, // 読み取ったバイト数
  LPOVERLAPPED lpOverlapped    // オーバーラップ構造体のバッファ
);

nNumberOfBytesToRead 
    読み取り対象のバイト数を指定します。 

-------------------------

上記の説明がご不明であれば、nNumberOfBytesToRead に 1 や 2 を指定し、
実行後 lpBuffer や lpNumberOfBytesRead を確認するとご理解いただけるかと。

# ご質問をまとめてピンポイントにすると、お望みの回答が得やすいかもしれません

ピースケ 2006/07/19(水) 16:55:56
すみません説明不足で・・・それと初心者です

バイナリファイルは256バイトです、この中で2,12,12,2,2,3,2,2,6,3,3,6バイトの
データがはいっています。データによってはプラス2,6バイトがはいっています。
この場合は全部で57バイト使用しています、256-57 = 199 この199バイトは
すべて 00 になっています。

ReadFile(hF, strFile, GetFileSize(hFile , NULL), &dwResult, NULL);
ReadFile(hF, &strFile, GetFileSize(hFile , NULL), &dwResult, NULL);
こうですね。

CStringにバイナリーデータは入らないのですか・・・
普通は、charの変数を準備して CStringに変換する形なんですか?

ReadFileは(ファイル, 読み取る場所の先頭アドレス, 読み取る最後, その値を格納, 
NULL)

ReadFile(hf,1バイト目のアドレス,2バイト目,&dwResult, NULL)
こうすると &dwResultの場所には 36 36 とはなる?

GlobalAlloc を使って先頭アドレスを取得するのかと思っています。
http://72.14.203.104/search?
q=cache:otstINKDyPgJ:www.microsoft.com/JAPAN/developer/library/jpwinpf/_win32_g
lobalalloc.htm+GlobalAlloc()&hl=ja&gl=jp&ct=clnk&cd=1&lr=lang_ja

また厳しい突っ込みお願い致します。

επιστημη 2006/07/19(水) 17:05:57
> バイナリファイルは256バイトです、この中で2,12,12,2,2,3,2,2,6,3,3,6バイトの
> データがはいっています。データによってはプラス2,6バイトがはいっています。
> この場合は全部で57バイト使用しています、256-57 = 199 この199バイトは
> すべて 00 になっています。

要するに57バイト読めばいいのですね?
「データによっては」とは如何なる意味ですか?

> ReadFile(hF, strFile, GetFileSize(hFile , NULL), &dwResult, NULL);
> ReadFile(hF, &strFile, GetFileSize(hFile , NULL), &dwResult, NULL);
> こうですね。

LPSTRが如何なる型か知らんけど、おそらく"違います"

> CStringにバイナリーデータは入らないのですか・・・

CStringは文字列を扱うものです。
そのバイナリデータの途中に'\0'があると、おそらく望む結果は得られないでしょう。
末尾のみ'\0'であればそのバイナリデータは文字列として扱えますから、CStringに
格納しても構わないと思われます。

> 普通は、charの変数を準備して CStringに変換する形なんですか?

通常いかなる手段であれ、バイナリデータをCStringに格納"しません"。
そのバイナリデータとやらが"実は文字列"であるならその限りではありませんが。

ピースケ 2006/07/19(水) 17:36:58
「データによっては」というのは取得するファイルによって違うという事です。

進行がゆっくりになってしまって申し訳ありません。

サンプルを少し改造して見ました、突っ込みよろしくお願いします。
コメントは僕なりの理解です。

LPBITMAPFILEHEADER    lpBf; // ビットマップはこれを使っているのですが
             // 今回の仕様に合うデータ型が分りません
hF = CreateFile
(FilePath,ENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

lpBf = GlobalAlloc(GPTR, sizeof('256'));  // lpBf にバッファのアドレスを取得
ReadFile(hF, lpBf, sizeof('256'), &dwResult, NULL); //ファイルの0〜256byteまで
                          //読み込む

επιστημη 2006/07/19(水) 17:42:28
>サンプルを少し改造して見ました、突っ込みよろしくお願いします。

サンプルって?

> sizeof('256')

なんだこりゃ?

# 無礼な物言いで申し訳ないけど、基礎ができてない。
# '背伸び'しすぎではないかしら?

ピースケ 2006/07/19(水) 18:11:39
すみません基礎が出来て無くって

いつもはこのような形でしかsizeofは使っていなかったので・・・

char DT[10];
memset(DT,'\0',sizeof(DT));

sizeof(256);でいいですか?

Ban 2006/07/19(水) 18:16:05
> すみません基礎が出来て無くって

# まずこれを作らないと、多分どうにもならないかも…。

> sizeof(256);でいいですか?

VC6だと多分 4 (intのサイズ)になりますが(256にはならない)、それで望み通りです
か?

REE 2006/07/19(水) 18:17:53
>memset(DT,'\0',sizeof(DT));

この時に、なぜ、何のためにsizeofを使うのかが
理解できていないのではありませんか?

ピースケ 2006/07/19(水) 18:28:50
そうですか・・・

256バイトの領域は確保できないのですか?

お手数かけます。テンパッテ冷静さをかいているので
もしバイナリーデータを読み込んで変数に入れる方法の参考に
なるHPとか知ってる方がいましたら教えて下さい。

落ち着いてから質問します。

tetrapod 2006/07/19(水) 19:05:30
別スレのほうで指摘があったとおりで LPSTR strFile; だけではメモリは無い。
だから対処方法は以下のどちらかになるわけです。

1.配列をつかう(自動変数などで)
char buf[256];
ReadFile(hF, buf, 256, ...);

2.動的メモリで確保する
char* strFile=new char [256]; // あるいは GlobalAlloc でもいいけど
ReadFile(hF, strFile, 256, ...);

sizeof を使うなら 1 は ReadFile(hF, buf, sizeof buf, ...)
2 は sizeof が要らない (使ってはいけない) 場合
マジックナンバー 256 を const や #define で書きなおすほうがいいけど。

>char DT[10];
>memset(DT,'\0',sizeof(DT));
この sizeof(DT) が出てくるようなら問題ない(理解できてる)はずです。
テンパッてませんか?落ち着いて。
sizeof(DT) と sizeof('256') と sizeof(256) の違いは重要ですよ。

三草 2006/07/19(水) 19:06:59
> ReadFileは(ファイル, 読み取る場所の先頭アドレス, 読み取る最後, その値を格納, 
NULL)
ちがいますよー
MSDNでReadFile()をよく読んでみてください。
書いてあることが分からなければ、Google等でサンプルソースや解説を探してみるのもよ
いかと。

ReadFile(ファイルのハンドル,
     読取ったデータの格納先,
     読取るバイト数,
     読取ったバイト数の格納先, 
     NULL)


> char DT[10];
> memset(DT,'\0',sizeof(DT));
> sizeof(256);でいいですか?
memset()の第3引数は何を指定するんでしょう?
http://www9.plala.or.jp/sgwr-t/lib/memset.html
sizeofは何をしているのでしょう?
http://phys.cool.ne.jp/physjpn/c2.htm#sec2

> 256バイトの領域は確保できないのですか?
char *szStr;
szStr = (char *)malloc( 256 );
# でも、マジックナンバーは極力使わないほうが、コード修正時に楽ですよ。

> すみません説明不足で・・・それと初心者です
初心者は関係ありませんよ、誰でも始めは初心者です。
私もまだまだ初心者ですし。
重箱の隅つつきですが、、、攻めるつもりはありません。
http://glossary.tank.jp/t004C.html
# ピースケさんがやりたいことをするには、どういう手順(コード)をふめばいいのか
# 一連の手順を紙に一つづつ書き出してみると、
# 何をやるべきか、何が分からないかが整理できるかもしれません。
# その上でご質問されてみてはいかがでしょうか?

# Q.文字列"36"を10進の 6 に直して、float m_lAaa に格納したいけれど、
# どういう方法がありますか?
# A.strtol()をお使いください。

# とか、きっとストレートな回答を得られるかと。
# がんばってください。

三草 2006/07/19(水) 19:21:11
> マジックナンバー 256 を const や #define で書きなおすほうがいいけど。
> # でも、マジックナンバーは極力使わないほうが、コード修正時に楽ですよ。
tetrapodさんもご指摘されていました。
ちょっと補足です。

#define READ_DATA_SIZE 256
//または、const int READ_DATA_SIZE = 256;  とか
・・・
char buf[READ_DATA_SIZE];
ReadFile(hF, buf, READ_DATA_SIZE, ...);
・・・

といった感じです。
コード中にいきなり 256 と出てきても、何の数字かぱっと分からないですよね。
例えば READ_DATA_SIZE とあれば、読み込むデータサイズだろうな、と予測できます。
また、読込み数が変わったときにも、#define もしくは const intの1箇所を
変えればいいだけなので、修正の手間も省けます。

ITO 2006/07/19(水) 19:26:31
まず、参考書等を購入されてじっくり勉強されたほうがいいと思います。
HPサイトを紹介してもいいのですが、サイトによって内容が違うので
基礎を知るには本を購入されるほうがいいと思います。

ピースケ 2006/07/19(水) 20:40:15
みなさんありがとうございます

Buf[256]にバイナリーデータを入れる事にしました。
バッファデータをmemsetを使用して一時変数に代入したのですが
それを目的の型への変換方法が分りません。
どうゆう方法があるか分る方がいましたらよろしくお願い致します。

char Buff[256];
char databox[13];

char Buff[256]の中にバイナリーデータを入れまた。

for(cnt = 0; cnt< 3 ;cnt++)
{
 memset(databox,'\0',sizeof(databox));
 switch(cnt)
 {
  case 0: 
         memcpy(databox, Buff,2);
         //databox の中身をlong型に変換する方法がわかりません
         //変換した値を long m_lAaa に入れたい
 case 1:
        memcpy(databox, Buff[2],12);
        //databox の中身をCString型に変換する方法がわかりません
    //変換した値を CString m_szBbb  に入れたい
  case 2:
        memcpy(databox, Buff[14],12);
        //databox の中身をCString型に変換する方法がわかりません
    //変換した値を CString m_szCcc  に入れたい

 case 2:
        memcpy(databox, Buff[26],12);
        //databox の中身をCString型に変換する方法がわかりません
    //変換した値を CString m_szDdd  に入れたい

 }
}

ピースケ 2006/07/19(水) 20:50:10
switch文のbreak;が抜けてます
すみません

Ban 2006/07/19(水) 22:19:21
どんなデータかもわからずに変換したいと言われましても…と思いますが。
それぞれのデータ形式の仕様提示してください。それにより変換の方法も違うでしょ
う。

         //databox の中身をlong型に変換する方法がわかりません
         //変換した値を long m_lAaa に入れたい

リトル/ビッグエンディアンですか。数字の文字列ですか。はてまたBCDですか。
何も考えなくていいなら、m_lAaa = *reinterpret_cast<unsigned short*>(databox);と
か。
# この意味がわからないなら、危険なので多分やめておいた無難です。


        memcpy(databox, Buff[2],12);
        //databox の中身をCString型に変換する方法がわかりません
    //変換した値を CString m_szBbb  に入れたい

こちらも同様です。文字コードはなんですか。Bufの中に終端('\0')はありますか。
CStringに格納できるもので終端があるなら(多分違いそうな気が…)以下のように。
CString m_szBbb = databox;
そうでないなら仕様を提示してください。

# 無理にループするよりは直接処理してしまうか、
# もしくはループするならインデクステーブルとポインタ変数で回した方が
# いいような気もしますが。

Ban 2006/07/19(水) 22:22:24
ごめんなさい、13でmemsetしてるから少なくとも終端はありますね。
後は中身次第ですが。


# (私見)生の即値が気持ち悪いです。

Ban 2006/07/20(木) 01:07:03
もしかして、

66
A5L100-006K
8.KASH....

って出力を期待してますか?
であれば、fscanfを調べるの
が早いかも知れない。

Ban 2006/07/20(木) 01:17:30
#三草 さんで既出だった…orz
つstrtol

PATIO 2006/07/20(木) 17:10:53
がーん、もう一個の方に書いてしまいました。
質問者のピースケさん、もう一つの方を解決で閉じるようにしてください。
同じスレがもう一つあってそっちで話が続いている事も書いて置いてくださいね。

ピースケ 2006/07/20(木) 21:14:59
[[解決]]
みなさんありがとうございました。
バイナリデータの読込みと型変換は以下の方法でやりました
またよろしくお願い致します。

switch(count)
 {
  case 0:
    memcpy(databox, Buff,2);
         m_lAaa = atol(chDataBox);
         break;
    case 1:
    memcpy(databox, &Buff[2],12);
         m_szBbb = databox
         break;
    case 2: 
         memcpy(databox, &Buff[26],12);
         m_szDdd = databox;
         break;
 }

古いスレッドには追加発言できません。