Cでバイナリ・パターンを検索する(読むにはバイナリファイルをバッファリング)
-
20-09-2019 - |
質問
ちょっとそこ。私は、バイナリまたは小数に簡単に変換することができ、「0xFFの0xC0のは0x00 0x11を」の最後に出現した後、次の4つのバイトを読み込みます小さなプログラムを書くことをしようとしています。目的は、六角形パターンの最後に出現する次の2-5バイトがJPEGファイルの幅と高さを表していることである。
#include <stdio.h>
int main () {
FILE * pFile;
long lSize;
char * buffer;
size_t result;
pFile = fopen ( "pano8sample.jpg" , "rb" );
if(pFile==NULL){
fputs ("File error",stderr);
exit (1);
}
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
printf("\n\nFile is %d bytes big\n\n", lSize);
buffer = (char*) malloc (sizeof(char)*lSize);
if(buffer == NULL){
fputs("Memory error",stderr);
exit (2);
}
result = fread (buffer,1,lSize,pFile);
if(result != lSize){
fputs("Reading error",stderr);
exit (3);
}
//0xFF 0xC0 0x00 0x11 (0x08)
//Logic to check for hex/binary/dec
fclose (pFile);
free (buffer);
return 0;
}
問題は、私は再帰的にバッファリングメモリから読み出されて、私のバイナリ/進/ 12月と比較するためにintとして最も最近読ん変数を使用する方法がわからないです。
どのように私はこれを行うのですか?
解決
byte needle[4] = {0xff, 0xc0, 0x00, 0x11};
byte *last_needle = NULL;
while (true) {
byte *p = memmem(buffer, lSize, needle, 4);
if (!p) break;
last_needle = p;
lSize -= (p + 4) - buffer;
buffer = p + 4;
}
last_needle
がnullでない場合は、プリントアウトすることができますlast_needle+4
...
他のヒント
の代わりにファイル全体をメモリに読み込んで、私は、ステートマシンのビットを使用します。私のCは少し錆びですが、ます:
char searchChars[] = {0xFF,0xC0,0x00,0x11};
char lastBytes[5];
int pos = 0; int curSearch = 0;
while(pos <= lSize) {
curChar = getc(pfile); pos++; /*readone char*/
if(curChar == searchChars[curSearch]) { /* found a match */
curSearch++; /* search for next char */
if(curSearch > 3) { /* found the whole string! */
curSearch = 0; /* start searching again */
read = fread(lastBytes,1,5,pfile); /* read 5 bytes */
pos += read; /* advance position by how much we read */
}
} else { /* didn't find a match */
curSearch = 0; /* go back to searching for first char */
}
}
は最後に、あなたは右、あなたがsearchCharsを見つける最後の時間が経過した後の5つのバイトをしているlastBytesで5つのバイトが残っている。
個人的に、私は、一度に1つの文字を飲み込み機能を使用すると思います。機能は、静的ローカル変数またはパラメータブロック構造の詳細を保存する、簡単な正規表現マッチを行うには有限状態マシンを使用します。一部が一致した状態のための1つの、そして最後の完全一致のための1 - - あなたは2つのサブブロックを必要とし、必要に応じて、それぞれが関連する位置や値を示す
。この場合、手動でこれを設計することができるはずです。より複雑な要件については、 Ragel を見ます。
あなたは、C / C ++でfscanf関数を使用することができます。そのない場合は、これを行います独自の機能を記述する必要があります。簡単な方法は、あなたがEOFになるまで続けたいパターンのバイトの文字列を検索し、ファイルからバイトのN量を読み取ることになります。
(あなたが探している行はファイルの先頭付近にある場合は不要。)あなたのコードは、実際にすべてを一度にファイル全体を読み込み、バイト配列(charはバイトと等価であるとしてあなたのコードは、ヒープ上のファイルを保存しますC ++で)と、メモリ内の連続する配列の先頭へのポインタをバッファリングします。あなたが他の配列を操作するのと同じようにバッファ配列を操作します。
また、あなたがするつもりであれば、の何でものあなたのサイズを読んだ後、あなたがリークを避けるために、mallocで割り当てられ、バッファオブジェクトを解放してくださいます。