avlファイルを read関数で読み込むには

解決


ほほ  2008-12-18 22:30:45  No: 69298  IP: 192.*.*.*

誰かが作ったAVLファイルをread関数を用いて読みこみたいのですが
肝心な部分を読みこめません。

ファイル中に

 0 K 92820  1100      ヨ # i?             = = = =

このような部分がありまして

 0 K 92820  1100  

こちらまでは読みこむことができるのですが
必要と思われる残りの部分を読みこめません。

VCもCもほとんど分からないのですが
何か良い方法はないでしょうか?

read関数では  読み込めない文字なのでしょうか?
lseek(fh, offset,SEEK_SET);  
read(fh, data, length2);

いただいたソースにはこんな感じで記述してあります。

なにかヒントをいただけると幸いに思います。
宜しくお願いします。

編集 削除
επιστημη  URL  2008-12-19 10:14:00  No: 69299  IP: 192.*.*.*

open時のmodeはどうなってます?

編集 削除
rin  2008-12-19 12:07:33  No: 69300  IP: 192.*.*.*

1:開発環境(OS、VCのバージョン)
2:作成してるアプリケーションの条件(リンクしてるライブラリなど)
3:読み込みたいファイルのオープンモード(意味わからなければ、ファイルオープンのソース)
4:読み込みデータをいれるバッファサイズ
5:read時のlength2の値
6:readの戻り値
7:ファイルに「 0 K 92820  1100      ヨ # i?             = = = =」があると確認した方法
8:「 0 K 92820  1100  」これしか読めていないと確認した方法

このあたりどうなってますか?

編集 削除
επιστημη  URL  2008-12-19 13:21:42  No: 69301  IP: 192.*.*.*

> 8:「 0 K 92820  1100  」これしか読めていないと確認した方法

ここらへんあやしぃすねー♪
バイナリデータを printf してたりなんかしたりして。
途中に '\0' があったらぷっつり切れるわけで。

編集 削除
ほほ  2008-12-19 23:52:44  No: 69302  IP: 192.*.*.*

>open時のmodeはどうなってます?
open(TmpPath, O_BINARY|O_RDONLY, _S_IREAD) 
こんな感じでOPENしています。

>1:開発環境(OS、VCのバージョン)
 OSは、Windows xp,Windows98  VC++6.0です。

>2:作成してるアプリケーションの条件(リンクしてるライブラリなど)
 よく分からないのですが
 VCで、DLLファイルを作って、エクセルより呼び出してテストしています。

>3:読み込みたいファイルのオープンモード(意味わからなければ、ファイルオープンのソース)
>4:読み込みデータをいれるバッファサイズ

>5:read時のlength2の値
 333です。
>6:readの戻り値
 
>7:ファイルに「 0 K 92820  1100      ヨ # i?             = = = =」があると確認した方法
 メモ帳やエディタで開くとこのようになっていました。

>8:「 0 K 92820  1100  」これしか読めていないと確認した方
   MessageBox( NULL, tmp22+_PLUS, "tmp22+_PLUS", MB_OK);
   これしか確認する方法がわかりません。
   
   tmp22+_PLUS  ==  「 0 K 92820  ・1100 」になります。
 
   struct AvlFile2 {
     struct AvlTree2 afs2;
     int    fh2;      /* ファイルハンドル  */
     int    cn2;      /* 読み込み済みレコード数*/
     union LongChar  ad2[_DEEP];  /* データのレコードアドレス*/
     char    lr2[_DEEP];  /* 読み込み左右フラグ  */
     char    *buff2;      /* 読み込みデータ格納領域  */
     char    *tmp12;      /* 作業データ領域1  */
     char    *tmp22;      /* 作業データ領域2  */
   };

   #define  _PLUS  (sizeof(long)+sizeof(long)+sizeof(char))  
                   /* 左右データアドレスとバランス  */

こんな感じになっております。

編集 削除
wclrp ( 'o')  2008-12-20 13:06:49  No: 69303  IP: 192.*.*.*

データは文字として表示できるものではないので文字列を表示したり
メモ帳などで確認するのは不可能。

途中までだが一致しているようなので恐らく成功している。
恐らく読み込めている。読み込めていないと思い込んでいるだけ。

readの戻り値をチェックしないのは駄目。
readの戻り値を使わないと実際に読み込めたデータのサイズは分らない。
文字列じゃないからstrlenとか文字列用のものはまず利用できない。

編集 削除
ほほ  2008-12-25 01:46:15  No: 69304  IP: 192.*.*.*

>readの戻り値は
333です。
こちらはread関数で読みこめるバイト数になるのでしょうか?

読み込み出来ない部分
”ヨ # i?             = = = =”
はある図形のX座標とY座標が入っていると思われます。
ゥ分としてはよく分からないのですが
これらの文字(?)はアスキーコードなのかな?と思ったりしています。

そこでAsciiコードを10進数に変換する方法を探していて

#include<iostream>    
using namespace std;

int main()
{
        
        char ss[1];
 datain:      
        cout<<"ASCIIコードを調べたい文字を入力して下さい:";cin>>ss;
       
        cout <<ss[0]<<"のコードは "<<(int)ss[0]<<" です。\n";

        if (ss[1]=='/') exit(0);  //2番目の文字が「/」のとき処理を終了します

        goto datain;
        
        return 0;
}

こちらを見つけたので確認しようと

char TmpBuff3[BUFSIZ];

ss  = 'A';
cin>>ss;

 sprintf(TmpBuff3, "%d",ss);
 MessageBox( NULL, TmpBuff3, "ss", MB_OK);


試して見たのですが 65 の値には成りません。

アスキーコードを10進数に変換する方法はどうしたらよいのでしょうか?
教えていただきたいです。

編集 削除
wclrp ( 'o')  2008-12-25 02:34:38  No: 69305  IP: 192.*.*.*

文字じゃないのにアスキーコードって呼ぶの変だな。
データの中に部分的に文字などが入っていることあるけどさ。

readの戻り値は読み込めるサイズではなく読み込みしたサイズでしょ。
戻り値が333なら333バイト読み込みできてます。
そもそもreadの戻り値を使用しないなんてまずい。

VisualStudioのデバッガでメモリを見ることできるよ。
 MessageBox( NULL, TmpBuff3, "ss", MB_OK);
なんてしなくても見ることできるのでデバッガ使うべき。
使えないわけでも?

tmp22+_PLUSから333バイトのデータが入っているということは
tmp22[_PLUS]
tmp22[_PLUS+1]
tmp22[_PLUS+2]
tmp22[_PLUS+3]
......
tmp22[_PLUS+332]
にちゃんとデータが入っているからもう確認しなくていいよ。

編集 削除
wclrp ( 'o')  2008-12-25 02:41:37  No: 69306  IP: 192.*.*.*

どうしてもって言うなら
sprintf(TmpBuff3, "%d",tmp22[_PLUS]);
MessageBox( NULL, TmpBuff3, "ss", MB_OK);

ただtmp22がたぶん符号ありのcharだから
127より大きい値は負の値となってしまうよ。

> cin>>ss;
邪魔

編集 削除
plus  2008-12-25 02:57:13  No: 69307  IP: 192.*.*.*

>VCもCもほとんど分からないのですが

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
  unsigned char ch;

  int fh = _open("d:\\kitty.avi", O_BINARY);
//                ↑ターゲットのファイル名
  for(int i=0;i<=50;i++) {
    read(fh, &ch, 1);
    printf("%x      %c\n",ch,ch);
  }
  close(fh);
}

これ単体で実行して結果を確認できますか?
また、何をしているか分かりますか?
#バカにしているわけではありません。

編集 削除
ほほ  2008-12-26 02:34:35  No: 69308  IP: 192.*.*.*

>どうしてもって言うなら
>sprintf(TmpBuff3, "%d",tmp22[_PLUS]);
>MessageBox( NULL, TmpBuff3, "ss", MB_OK);

確認することができました!

>ただtmp22がたぶん符号ありのcharだから
>127より大きい値は負の値となってしまうよ。

確かに-40とかの負の値がありました。

正の値と、負の値の関係がよくわかりません。
>127より大きい値は負の値
ということは
-40は 127+40で168だったりするのですか(?)
↑これは違うような気がするのですが…
この場合、-40はどんな値か教えていただけませんか?

編集 削除
wclrp ( 'o')  2008-12-26 07:37:04  No: 69309  IP: 192.*.*.*

char型を文字でなく数値とした場合
一般的には8ビットの2の補数による符号ありなので。

頻繁にchar*型を符号なしにするの面倒だから
unsigned char * data22 = (unsigned char *)tmp22;
符号なし8ビットにするとか。

編集 削除
ほほ  2008-12-27 01:21:45  No: 69310  IP: 192.*.*.*

wclrp ( 'o')さん
親切丁寧に教えていただいて
なにからなにまで有難うございます。

おかげさまで
データを抽出することができましたし
言語を一歩踏み込み
少しですが理解も深まりました。

自分の課題を完結するには
もうひとひねりしなければ成りませんが
チャレンジしてみようと思います。

本当に有難うございました!!

編集 削除