2

ちょっと、そこ。簡単に 2 進数または 10 進数に変換できる "0xFF 0xC0 0x00 0x11" が最後に出現した後の 4 バイトを読み取る小さなプログラムを作成しようとしています。その目的は、その 16 進数パターンの最後の発生に続く 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;
 }

問題は、バッファリングされたメモリから再帰的に読み取る方法がわからず、最近読み取った変数を int として使用してバイナリ/16 進数/10 進数と比較する方法がわからないことです。

どうすればいいですか?

4

5 に答える 5

9
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;
}

nullでない場合last_needleは、印刷できますlast_needle+4...

于 2009-10-09T04:37:23.003 に答える
2

ファイル全体をメモリに読み込む代わりに、ちょっとしたステート マシンを使用します。私の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 バイトが残っています。

于 2009-10-09T04:45:30.780 に答える
1

個人的には、一度に 1 文字ずつ飲み込む関数を使用します。この関数は、有限状態マシンを使用して単純な正規表現の照合を行い、詳細を静的ローカル変数またはパラメーター ブロック構造に保存します。部分一致状態用と最後の完全一致用の 2 つのサブブロックが必要です。それぞれが必要に応じて関連する位置または値を示します。

この場合、これを手動で設計できるはずです。より複雑な要件については、Ragelを参照してください。

于 2009-10-09T04:39:15.887 に答える
0

データがASCIIでエンコードされている場合は、C /C++でfscanf関数を使用できます。そうでない場合は、これを行う独自の関数を作成する必要があります。簡単な方法は、ファイルからNバイトを読み取り、バイト文字列で目的のパターンを検索してから、EOFまで続行することです。

コードは実際にファイル全体を一度に読み取ります(探している行がファイルの先頭近くにある場合は不要です)。コードはファイルをバイト配列としてヒープに格納します(charはC ++のバイトに相当します)バッファを使用して、メモリ内の連続する配列の先頭へのポインタ。他のアレイを操作するのと同じように、バッファアレイを操作します。

また、サイズを読み取った後で何かを行う場合は、リークを回避するために、mallocされたバッファオブジェクトを解放してください。

于 2009-10-09T04:34:39.383 に答える