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 se pueden convertir fácilmente a binario o decimal. El propósito es que el 2-5 bytes después de la última aparición 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é cómo leer el búfer de memoria de forma recursiva y uso de la más leído recientemente variable como un int para comparar contra mi binario/hexadecimal/dec.

¿Cómo puedo hacer esto?

OriginalEl autor Supernovah | 2009-10-09

4 Comentarios

  1. 6
    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 null, usted puede imprimir last_needle+4

    El memmem() función no está estandarizado por POSIX, pero está disponible en Linux y AIX, pero no en mac Os X (10.5) o Solaris 10.
    Para aquellos sin un memmem aplicación, os lo dejo como ejercicio para el lector…
    memmem() no parecen estar disponibles en OSX developer.apple.com/legacy/library/documentation/Darwin/… también lo veo usando hombre memmem (OSX 10.11.6)

    OriginalEl autor Keith Randall

  2. 2

    lugar de leer todo el archivo en la memoria, me gustaría utilizar un poco de una máquina de estado. 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, te deja con 5 bytes en lastBytes que son los cinco bytes justo después de la última vez que encuentre searchChars

    OriginalEl autor Igor Serebryany

  3. 1

    Personalmente, yo uso una función que se traga un carácter a la vez. La función se utiliza una máquina de estados finitos para hacer una simple coincidencia de la expresión regular, el ahorro de los detalles en una cualquiera de las variables locales estáticas o un bloque de parámetros de la estructura. Se necesitan dos sub-bloques, uno para la parte pareados estado, y uno para el último partido completo – cada uno indicando los puestos relevantes o valor según sea necesario.

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

    OriginalEl autor Steve314

  4. 0

    Puede utilizar la función fscanf en C/C++ si los datos son codificados en ascii. Si no, usted tendrá que escribir su propia función que va a hacer esto. Forma sencilla sería leer N cantidad de bytes del archivo, la búsqueda de la cadena de bytes para el patrón que desea, a continuación, continuar hasta EF.

    El código realmente lee el archivo completo de todos a la vez (innecesario si la línea de lo que buscas está 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 buffer con el puntero al inicio de la contiguos matriz en la memoria. Manipular la matriz de amortiguamiento igual que manipular cualquier otra matriz.

    También, si usted tiene la intención de hacer nada después de haber leído el tamaño, asegúrese de que usted se libre de la malloced búfer objeto de evitar una fuga.

    a la derecha.. fgetc en un r+b archivo volverá entero binario valores sí?
    porque parece estar regresando basura valores. ¿Cómo puedo comparar la última fgetc resultado en un valor binario de 8 bits byte?
    Yo no uso fgetc mucho pero creo que devuelve un byte de la posición actual del archivo interno de la posición.
    quieres echar el resultado que se obtiene a partir de fgetc a un unsigned char (lo que significa que un valor de 0 a 255), a continuación, compare. Un char tiene valor negativo representación demasiado para lo que es, probablemente, atornillando.
    o también se puede comparar a un valor hexadecimal. Sólo predend lo que usted quiere comparar con 0x y el compilador sabe que usted desea comparar valores hexadecimales.

    OriginalEl autor ldog

Dejar respuesta

Please enter your comment!
Please enter your name here