誰かが作ったAVLファイルをread関数を用いて読みこみたいのですが
肝心な部分を読みこめません。
ファイル中に
0 K 92820 1100 ヨ # i? = = = =
このような部分がありまして
0 K 92820 1100
こちらまでは読みこむことができるのですが
必要と思われる残りの部分を読みこめません。
VCもCもほとんど分からないのですが
何か良い方法はないでしょうか?
read関数では 読み込めない文字なのでしょうか?
lseek(fh, offset,SEEK_SET);
read(fh, data, length2);
いただいたソースにはこんな感じで記述してあります。
なにかヒントをいただけると幸いに思います。
宜しくお願いします。
open時のmodeはどうなってます?
編集 削除1:開発環境(OS、VCのバージョン)
2:作成してるアプリケーションの条件(リンクしてるライブラリなど)
3:読み込みたいファイルのオープンモード(意味わからなければ、ファイルオープンのソース)
4:読み込みデータをいれるバッファサイズ
5:read時のlength2の値
6:readの戻り値
7:ファイルに「 0 K 92820 1100 ヨ # i? = = = =」があると確認した方法
8:「 0 K 92820 1100 」これしか読めていないと確認した方法
このあたりどうなってますか?
> 8:「 0 K 92820 1100 」これしか読めていないと確認した方法
ここらへんあやしぃすねー♪
バイナリデータを printf してたりなんかしたりして。
途中に '\0' があったらぷっつり切れるわけで。
>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))
/* 左右データアドレスとバランス */
こんな感じになっております。
データは文字として表示できるものではないので文字列を表示したり
メモ帳などで確認するのは不可能。
途中までだが一致しているようなので恐らく成功している。
恐らく読み込めている。読み込めていないと思い込んでいるだけ。
readの戻り値をチェックしないのは駄目。
readの戻り値を使わないと実際に読み込めたデータのサイズは分らない。
文字列じゃないからstrlenとか文字列用のものはまず利用できない。
>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進数に変換する方法はどうしたらよいのでしょうか?
教えていただきたいです。
文字じゃないのにアスキーコードって呼ぶの変だな。
データの中に部分的に文字などが入っていることあるけどさ。
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]
にちゃんとデータが入っているからもう確認しなくていいよ。
どうしてもって言うなら
sprintf(TmpBuff3, "%d",tmp22[_PLUS]);
MessageBox( NULL, TmpBuff3, "ss", MB_OK);
ただtmp22がたぶん符号ありのcharだから
127より大きい値は負の値となってしまうよ。
> cin>>ss;
邪魔
>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);
}
これ単体で実行して結果を確認できますか?
また、何をしているか分かりますか?
#バカにしているわけではありません。
>どうしてもって言うなら
>sprintf(TmpBuff3, "%d",tmp22[_PLUS]);
>MessageBox( NULL, TmpBuff3, "ss", MB_OK);
確認することができました!
>ただtmp22がたぶん符号ありのcharだから
>127より大きい値は負の値となってしまうよ。
確かに-40とかの負の値がありました。
正の値と、負の値の関係がよくわかりません。
>127より大きい値は負の値
ということは
-40は 127+40で168だったりするのですか(?)
↑これは違うような気がするのですが…
この場合、-40はどんな値か教えていただけませんか?
char型を文字でなく数値とした場合
一般的には8ビットの2の補数による符号ありなので。
頻繁にchar*型を符号なしにするの面倒だから
unsigned char * data22 = (unsigned char *)tmp22;
符号なし8ビットにするとか。
wclrp ( 'o')さん
親切丁寧に教えていただいて
なにからなにまで有難うございます。
おかげさまで
データを抽出することができましたし
言語を一歩踏み込み
少しですが理解も深まりました。
自分の課題を完結するには
もうひとひねりしなければ成りませんが
チャレンジしてみようと思います。
本当に有難うございました!!