-1

このプログラムが16進ファイルを正しく読み取らないのはなぜですか?

#include <stdio.h>
#include <stdlib.h>

char *buffer;
unsigned int fileLen;
void ReadFile(char *name);


void ReadFile(char *name)
{
        FILE *file;

        file = fopen(name, "rb");
        if (!file)
        {
                fprintf(stderr, "Unable to open file %s", name);
                return;
        }

        //Getting file length
        fseek(file, 0, SEEK_END);
        fileLen=ftell(file);
        fseek(file, 0, SEEK_SET);

        //Allocating memory
        buffer=(char *)malloc(fileLen+1);
        if (!buffer)
        {
                fprintf(stderr, "Mem error!");
                                fclose(file);
                return;
        }

        fread(buffer, fileLen, 1, file);
        fclose(file);


}

int main()
{
   var32 code;
   char filename[20];
   printf("Enter the file name: ");
   scanf("%s", &filename);
   ReadFile(filename);
   printf("FIle contents: %x\n",buffer);

}

巨大な16進ファイルを印刷すると、5〜6桁しか印刷されません。

4

3 に答える 3

6
printf("FIle contents: %x\n",buffer);

「%x」は、1つの16進値を出力するだけです。バッファの内容ではなく、バッファのメモリアドレスを出力しています。

変更してみてください:

    fread(buffer, fileLen, 1, file);
    fclose(file);

後で追加:

    ...
    fclose(file);
    size_t i;
    for (i = 0; i < fileLen; i++)
        printf("%02x ", buffer[i];

これにより、バイナリコンテンツ全体が印刷されます。ただし、これを行うためにファイル全体を読み取る必要はありません。たとえば、一度に1Kのブロックを出力できます...

別の実装

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#define BUFFER_SIZE     4096
int main(void)
{
     uint8_t  *buffer;  // Explicit 8 bit unsigned, but should equal "unsigned char"
     FILE     *file;
     char     filename[512];
     // We could also have used buffer[BUFFER_SIZE], but this shows memory alloc
     if (NULL == (buffer = malloc(BUFFER_SIZE)))
     {
          fprintf(stderr, "out of memory\n");
          return -1;
     }
     printf("Enter the file name: ");
     // Read a line terminated by LF. Max filename size is MAXPATH, or 512
     fgets(filename, 512, stdin);
     // Trim filename (Windows: CHECK we don't get \r instead of \n!)
     {
         // Being inside a { }, crlf won't be visible outside, which is good.
         char     *crlf;
         if (NULL != (crlf = strchr(filename, '\n')))
              *crlf = 0x0;
     }
     if (NULL == (file = fopen(filename, "rb")))
     {
         fprintf(stderr, "File not found: '%s'\n", filename);
         return -1;
     }
     while(!feof(file) && !ferror(file))
     {
          size_t i, n;
          if (0 == (n = (size_t)fread(buffer, sizeof(uint8_t), BUFFER_SIZE, file)))
               if (ferror(file))
                    fprintf(stderr, "Error reading from %s\n", filename);
                    // Here, n = 0, so we don't need to break: next i-cycle won't run
          for (i = 0; i < n; i++)
          {
               printf("%02x ", buffer[i]);
               if (15 == (i % 16))
                    printf("\n"); // Every 16th byte, a newline
          }
     }
     fclose(file); // file = NULL; // This ensures file won't be useable after fclose
     free(buffer); // buffer = NULL; // This ensures buffer won't be useable after free
     printf("\n");
     return 0;
}
于 2012-07-09T12:50:40.710 に答える
4

このprintf()ステートメントは、のアドレスをbuffer16進形式で出力します。printf()各バイトを入力する必要がありbuffer呼び出し元がいつ停止するか、呼び出し元にバイト数を返すようにnull終了する必要がありますbufferbuffer)、呼び出し元が何バイト入っているかを確認しますbuffer(null終了はバイナリで読み取るので安全ではありません) 。

また:

  • 逆参照する前にnullでないことを確認bufferしてください(バイトごとに出力するために必要です)
  • の戻り値をチェックして、fread()成功したことを確認します
  • free()不要になったときにバッファリングすることを忘れないでください
  • 不要な戻り値のキャストmalloc()mallocの結果をキャストしますか?を参照)
  • scanf()バッファオーバーランを回避するために、読み取られるバイト数を制限します。scanf("%19s", filename);
  • code未使用のローカル変数です
于 2012-07-09T12:50:45.143 に答える
-1

16進数でバイナリを意味する場合、それらを直接印刷することはできません。出力はファイルの最初のゼロバイトで終了します。

また、ファイルが見つからない場合は、最初に「ファイルを開けません」と言ってから、「ファイルの内容:...」と続けてください。

そして、他の人が指摘しているように、あなたはバッファを間違った方法で印刷しています。

そして、あなたはバッファを解放しません。

于 2012-07-09T12:48:30.470 に答える