Pregunta

Hola. Estoy tratando de escribir un pequeño programa que lea los siguientes cuatro bytes después de la última aparición de "0xFF 0xC0 0x00 0x11" que pueden ser fácilmente convertidos a binario o decimal. El propósito es que los 2-5 bytes siguientes a la última ocurrencia de ese patrón hexagonal representan la anchura y la altura de un archivo 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;
 }

El problema es que no sé leer de la memoria buffer de forma recursiva y utilizar la variable más leído recientemente como un int con el que comparar mi binario / Hex / DEC.

¿Cómo se hace esto?

¿Fue útil?

Solución

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

Si last_needle no es nulo, se puede imprimir last_needle+4 ...

Otros consejos

en lugar de leer todo el archivo en la memoria, me gustaría utilizar un poco de una máquina de estados. Mi C es un poco oxidado, pero:

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 */
    }
 }

al final, uno se queda con 5 bytes en lastBytes que son los cinco bytes inmediatamente después de la última vez que encuentre searchChars

En lo personal, me gustaría usar una función que se traga un carácter a la vez. La función utilizará una máquina de estados finitos para hacer una simple coincidencia de expresiones regulares, ahorrando detalles en unos variables locales, ya sea estática o una estructura de bloque de parámetros. Se necesitan dos sub-bloques - una para el estado parte a juego, y uno para el último partido completo - cada uno que indica las posiciones o valor pertinentes, según sea necesario

.

En este caso, usted debe ser capaz de diseñar manualmente. Para conocer los requisitos más complejos, mira Ragel .

Puede utilizar la función fscanf en C / C ++, si los datos están codificados en ASCII. Si no es, usted tendrá que escribir su propia función que va a hacer esto. Una manera sencilla sería leer cantidad de N bytes del archivo, buscar la cadena de bytes para el patrón que desee y luego continuar hasta que EOF.

Su código realmente lee el archivo completo de una sola vez (no es necesario si la línea que busca es cerca de la parte superior del archivo.) El código almacena el archivo en el montón como una matriz de bytes (char es equivalente a un byte en C ++) con tampón el puntero al comienzo de la matriz contiguos en la memoria. Manipular la matriz del separador igual que lo haría manipular cualquier otra matriz.

Además, si usted tiene la intención de hacer lo después de haber leído el tamaño, asegúrese de hacer el objeto búfer malloced para evitar una fuga.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top