读取二进制文件 - 分段错误

Read Binary File - Segmentation fault

我正在尝试读取二进制文件的内容。我目前可以读取文件,但是无法读取文件的全部内容,因为软件returns终端错误(Segmentation fault),怎么回事使用我的代码?

我的输出:

0 0 0 0 0 0 0 0 0 0 a0 f2 41 0 0 0 0 0 88 be e8 b2 fd 7f 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 b3 60 5f 7c 6 7f 0 0 0 0 0 0 0 0 0 0 88 be e8 b2 fd 7f 0 0 a0 c4 7b 7c 2 0 0 0 80 11 40 0 0 0 0 0 d0 12 40 0 0 0 0 0 49 d2 9f 81 bc c5 24 f0 90 10 40 0 0 0 0 0 80 be e8 b2 fd 7f 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 d2 df fa 6d a0 df f 49 d2 51 41 2 3d 28 e 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 88 be e8 b2 fd 7f 0 0 a0 be e8 b2 fd 7f 0 0 90 d1 98 7c 6 7f 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 90 10 40 0 0 0 0 0 80 be e8 b2 fd 7f 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 be 10 40 0 0 0 0 0 78 be e8 b2 fd 7f 0 0 1c 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 c3 dc e8 b2 fd 7f 0 0 cd dc e8 b2 fd 7f 0 0 0 0 0 0 0 0 0 0 d6 dc e8 b2 fd 7f 0 0 e6 dc e8 b2 fd 7f 0 0 f9 dc e8 b2 fd 7f 0 0 c dd e8 b2 fd 7f 0 0 21 dd e8 b2 fd 7f 0 0 43 dd e8 b2 fd 7f 0 0 5c dd e8 b2 fd 7f 0 0 6f dd e8 b2 fd 7f 0 0 99 dd e8 b2 fd 7f 0 0 f5 dd e8 b2 fd 7f 0 0 8 de e8 b2 fd 7f 0 0 24 de e8 b2 fd 7f 0 0 4c de e8 b2 fd 7f 0 0 68 de e8 b2 fd 7f 0 0 8b de e8 b2 fd 7f 0 0 a6 de e8 b2 fd 7f 0 0 c3 de e8 b2 fd 7f 0 0 dc de e8 b2 fd 7f 0 0 f3 de e8 b2 fd 7f 0 0 2a df e8 b2 fd 7f 0 0 43 df e8 b2 fd 7f 0 0 70 df e8 b2 fd 7f 0 0 81 df e8 b2 fd 7f 0 0 a1 df e8 b2 fd 7f 0 0 c4 df e8 b2 fd 7f 0 0 e3 df e8 b2 fd 7f 0 0 11 e0 e8 b2 fd 7f 0 0 29 e0 e8 b2 fd 7f 0 0 47 e0 e8 b2 fd 7f 0 0 60 e0 e8 b2 fd 7f 0 0 7f e0 e8 b2 fd 7f 0 0 9a e0 e8 b2 fd 7f 0 0 b4 e0 e8 b2 fd 7f 0 0 ce e0 e8 b2 fd 7f 0 0 97 e1 e8 b2 fd 7f 0 0 a7 e1 e8 b2 fd 7f 0 0 bb e1 e8 b2 fd 7f 0 0 ef e1 e8 b2 fd 7f 0 0 18 e2 e8 b2 fd 7f 0 0 2d e2 e8 b2 fd 7f 0 0 46 e2 e8 b2 fd 7f 0 0 aa e2 e8 b2 fd 7f 0 0 c0 e2 e8 b2 fd 7f 0 0 da e2 e8 b2 fd 7f 0 0 7 e3 e8 b2 fd 7f 0 0 26 e3 e8 b2 fd 7f 0 0 58 e3 e8 b2 fd 7f 0 0 85 e3 e8 b2 fd 7f 0 0 99 e3 e8 b2 fd 7f 0 0 b1 e3 e8 b2 fd 7f 0 0 da e3 e8 b2 fd 7f 0 0 e6 e3 e8 b2 fd 7f 0 0 6 e4 e8 b2 fd 7f 0 0 1c e4 e8 b2 fd 7f 0 0 2e e4 e8 b2 fd 7f 0 0 40 e4 e8 b2 fd 7f 0 0 65 e4 e8 b2 fd 7f 0 0 28 e5 e8 b2 fd 7f 0 0 47 e5 e8 b2 fd 7f 0 0 58 e5 e8 b2 fd 7f 0 0 71 e5 e8 b2 fd 7f 0 0 a4 e5 e8 b2 fd 7f 0 0 c4 e5 e8 b2 fd 7f 0 0 e9 e5 e8 b2 fd 7f 0 0 19 e6 e8 b2 fd 7f 0 0 35 e6 e8 b2 fd 7f 0 0 54 e6 e8 b2 fd 7f 0 0 79 e6 e8 b2 fd 7f 0 0 ac e6 e8 b2 fd 7f 0 0 c9 e6 e8 b2 fd 7f 0 0 fc e6 e8 b2 fd 7f 0 0 2d e7 e8 b2 fd 7f 0 0 44 e7 e8 b2 fd 7f 0 0 54 e7 e8 b2 fd 7f 0 0 68 e7 e8 b2 fd 7f 0 0 92 e7 e8 b2 fd 7f 0 0 9f e7 e8 b2 fd 7f 0 0 ba e7 e8 b2 fd 7f 0 0 ed e7 e8 b2 fd 7f 0 0 b8 e8 e8 b2 fd 7f 0 0 dc e8 e8 b2 fd 7f 0 0 f2 e8 e8 b2 fd 7f 0 0 1d e9 e8 b2 fd 7f 0 0 3b e9 e8 b2 fd 7f 0 0 64 e9 e8 b2 fd 7f 0 0 7a e9 e8 b2 fd 7f 0 0 8d e9 e8 b2 fd 7f 0 0 c4 e9 e8 b2 fd 7f 0 0 eb e9 e8 b2 fd 7f 0 0 fa e9 e8 b2 fd 7f 0 0 1e ea e8 b2 fd 7f 0 0 4a ea e8 b2 fd 7f 0 0 7e ea e8 b2 fd 7f 0 0 8f ea e8 b2 fd 7f 0 0 a0 ea e8 b2 fd 7f 0 0 b2 ea e8 b2 fd 7f 0 0 d2 ea e8 b2 fd 7f 0 0 dc ea e8 b2 fd 7f 0 0 e9 ea e8 b2 fd 7f 0 0 16 eb e8 b2 fd 7f 0 0 32 eb e8 b2 fd 7f 0 0 67 eb e8 b2 fd 7f 0 0 83 eb e8 b2 fd 7f 0 0 9d eb e8 b2 fd 7f 0 0 bf eb e8 b2 fd 7f 0 0 d1 eb e8 b2 fd 7f 0 0 e1 eb e8 b2 fd 7f 0 0 f6 eb e8 b2 fd 7f 0 0 8 ec e8 b2 fd 7f 0 0 2e ec e8 b2 fd 7f 0 0 56 ec e8 b2 fd 7f 0 0 71 ec e8 b2 fd 7f 0 0 84 ec e8 b2 fd 7f 0 0 9a ec e8 b2 fd 7f 0 0 b0 ec e8 b2 fd 7f 0 0 da ec e8 b2 fd 7f 0 0 f4 ec e8 b2 fd 7f 0 0 1e ed e8 b2 fd 7f 0 0 4e ed e8 b2 fd 7f 0 0 66 ed e8 b2 fd 7f 0 0 91 ed e8 b2 fd 7f 0 0 ab ed e8 b2 fd 7f 0 0 cc ed e8 b2 fd 7f 0 0 e6 ed e8 b2 fd 7f 0 0 7 ee e8 b2 fd 7f 0 0 3f ee e8 b2 fd 7f 0 0 5b ee e8 b2 fd 7f 0 0 7a ee e8 b2 fd 7f 0 0 8e ee e8 b2 fd 7f 0 0 a4 ee e8 b2 fd 7f 0 0 ba ee e8 b2 fd 7f 0 0 ce ee e8 b2 fd 7f 0 0 e5 ee e8 b2 fd 7f 0 0 ff ee e8 b2 fd 7f 0 0 27 ef e8 b2 fd 7f 0 0 38 ef e8 b2 fd 7f 0 0 f5 ef e8 b2 fd 7f 0 0 32 f0 e8 b2 fd 7f 0 0 4d f0 e8 b2 fd 7f 0 0 5f f0 e8 b2 fd 7f 0 0 8e f0 e8 b2 fd 7f 0 0 bd f0 e8 b2 fd 7f 0 0 d8 f0 e8 b2 fd 7f 0 0 15 f1 e8 b2 fd 7f 0 0 2e f1 e8 b2 fd 7f 0 0 58 f1 e8 b2 fd 7f 0 0 70 f1 e8 b2 fd 7f 0 0 8a f1 e8 b2 fd 7f 0 0 96 f1 e8 b2 fd 7f 0 0 b1 f1 e8 b2 fd 7f 0 0 df f1 e8 b2 fd 7f 0 0 fc f1 e8 b2 fd 7f 0 0 d f2 e8 b2 fd 7f 0 0 3e f2 e8 b2 fd 7f 0 0 4b f2 e8 b2 fd 7f 0 0 62 f2 e8 b2 fd 7f 0 0 8c f2 e8 b2 fd 7f 0 0 b8 f2 e8 b2 fd 7f 0 0 f2 f2 e8 b2 fd 7f 0 0 21 f3 e8 b2 fd 7f 0 0 42 f3 e8 b2 fd 7f 0 0 5b f3 e8 b2 fd 7f 0 0 6b f3 e8 b2 fd 7f 0 0 7c f3 e8 b2 fd 7f 0 0 96 f3 e8 b2 fd 7f 0 0 a1 f3 e8 b2 fd 7f 0 0 c4 f3 e8 b2 fd 7f 0 0 cc f3 e8 b2 fd 7f 0 0 f5 f3 e8 b2 fd 7f 0 0 16 f4 e8 b2 fd 7f 0 0 40 f4 e8 b2 fd 7f 0 0 4f f4 e8 b2 fd 7f 0 0 8f f4 e8 b2 fd 7f 0 0 b1 f4 e8 b2 fd 7f 0 0 cc f4 e8 b2 fd 7f 0 0 e1 f4 e8 b2 fd 7f 0 0 f8 f4 e8 b2 fd 7f 0 0 12 f5 e8 b2 fd 7f 0 0 3a f5 e8 b2 fd 7f 0 0 5d f5 e8 b2 fd 7f 0 0 df f5 e8 b2 fd 7f 0 0 b f6 e8 b2 fd 7f 0 0 45 f6 e8 b2 fd 7f 0 0 5c f6 e8 b2 fd 7f 0 0 75 f6 e8 b2 fd 7f 0 0 b1 f6 e8 b2 fd 7f 0 0 d6 f6 e8 b2 fd 7f 0 0 ef f6 e8 b2 fd 7f 0 0 61 f7 e8 b2 fd 7f 0 0 72 f7 e8 b2 fd 7f 0 0 bb f7 e8 b2 fd 7f 0 0 d9 f7 e8 b2 fd 7f 0 0 ea f7 e8 b2 fd 7f 0 0 3 f8 e8 b2 fd 7f 0 0 18 f8 e8 b2 fd 7f 0 0 33 f8 e8 b2 fd 7f 0 0 5b f8 e8 b2 fd 7f 0 0 77 f8 e8 b2 fd 7f 0 0 91 f8 e8 b2 fd 7f 0 0 a5 f8 e8 b2 fd 7f 0 0 bc f8 e8 b2 fd 7f 0 0 d2 f8 e8 b2 fd 7f 0 0 f4 f8 e8 b2 fd 7f 0 0 b f9 e8 b2 fd 7f 0 0 27 f9 e8 b2 fd 7f 0 0 4a f9 e8 b2 fd 7f 0 0 59 f9 e8 b2 fd 7f 0 0 7e f9 e8 b2 fd 7f 0 0 ab f9 e8 b2 fd 7f 0 0 cc f9 e8 b2 fd 7f 0 0 f4 f9 e8 b2 fd 7f 0 0 e fa e8 b2 fd 7f 0 0 22 fa e8 b2 fd 7f 0 0 52 fb e8 b2 fd 7f 0 0 89 fb e8 b2 fd 7f 0 0 c1 fb e8 b2 fd 7f 0 0 1b fc e8 b2 fd 7f 0 0 35 fc e8 b2 fd 7f 0 0 55 fc e8 b2 fd 7f 0 0 79 fc e8 b2 fd 7f 0 0 87 fc e8 b2 fd 7f 0 0 a7 fc e8 b2 fd 7f 0 0 d7 fc e8 b2 fd 7f 0 0 10 fd e8 b2 fd 7f 0 0 47 fd e8 b2 fd 7f 0 0 65 fd e8 b2 fd 7f 0 0 8e fd e8 b2 fd 7f 0 0 a4 fd e8 b2 fd 7f 0 0 ba fd e8 b2 fd 7f 0 0 e4 fd e8 b2 fd 7f 0 0 13 fe e8 b2 fd 7f 0 0 31 fe e8 b2 fd 7f 0 0 44 fe e8 b2 fd 7f 0 0 6a fe e8 b2 fd 7f 0 0 8b fe e8 b2 fd 7f 0 0 a2 fe e8 b2 fd 7f 0 0 c8 fe e8 b2 fd 7f 0 0 e2 fe e8 b2 fd 7f 0 0 fa fe e8 b2 fd 7f 0 0 36 ff e8 b2 fd 7f 0 0 4a ff e8 b2 fd 7f 0 0 5c ff e8 b2 fd 7f 0 0 91 ff e8 b2 fd 7f 0 0 ae ff e8 b2 fd 7f 0 0 c4 ff e8 b2 fd 7f 0 0 e2 ff e8 b2 fd 7f 0 0 0 0 0 0 0 0 0 0 21 0 0 0 0 0 0 0 0 e0 f5 b2 fd 7f 0 0 10 0 0 0 0 0 0 0 ff fb 8b 1f 0 0 0 0 6 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 11 0 0 0 0 0 0 0 64 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 40 0 40 0 0 0 0 0 4 0 0 0 0 0 0 0 38 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 b 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 e0 95 7c 6 7f 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 0 0 0 0 0 0 0 90 10 40 0 0 0 0 0 b 0 0 0 0 0 0 0 e8 3 0 0 0 0 0 0 c 0 0 0 0 0 0 0 e8 3 0 0 0 0 0 0 d 0 0 0 0 0 0 0 e8 3 0 0 0 0 0 0 e 0 0 0 0 0 0 0 e8 3 0 0 0 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 0 0 0 0 0 0 0 99 c7 e8 b2 fd 7f 0 0 1a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1f 0 0 0 0 0 0 0 ee ff e8 b2 fd 7f 0 0 f 0 0 0 0 0 0 0 a9 c7 e8 b2 fd 7f 0 0 0 0 0 0 0 0 0 

我的代码:

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

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("Usage: Please insert the file to recover photos\n");
        return 1;
    }
    else
    {
        FILE *file;

        unsigned char buffer[10];

        file = fopen(argv[1], "rb");

        long posicao = ftell(file);

        printf("Ponteiro no Inicio %ld\n", posicao);

        fseek(file, 0, SEEK_END);

        posicao = ftell(file);

        printf("Ponteiro no Fim: %ld\n",posicao);

        //Cannot open file
        if (file == NULL)
        {
            printf("Cannot open file \n");
            exit(0);
        }
        else
        {
            //Read the content
            fread(buffer, sizeof(buffer), 1, file);

            for(int i = 0; i < posicao; i++)
            {
                printf("%x ", buffer[i]); // prints a series of bytes
            }
        }
    }
}

谢谢

代码尝试写入超过 buffer[] 的末尾。
不打印多读。

// fread(buffer, sizeof(buffer), 1, file);
// for(int i = 0; i < posicao; i++)

size_t n = fread(buffer, 1, sizeof(buffer), file);
for(size_t i = 0; i < n; i++)

在正确的地方添加错误检查。

要读取超过 10 个,请分配内存或使用可变长度数组 (VLA)。 VLA 需要更多测试以确保其大小不为 0(容易)并且不会太大(很难做到)。

    FILE *file = fopen(argv[1], "rb");
    if (file == NULL) {
        printf("Cannot open file\n");
        exit(EXIT_FAILURE);
    }

    if (fseek(file, 0, SEEK_END)) {
        printf("Cannot fseek\n");
        exit(EXIT_FAILURE);
    }
    rewind(file); // Go back to beginning

    long posicao = ftell(file);
    if (posicao == -1 || (unsigned long) posicao > SIZE_MAX) {
        printf("Trouble with ftell %ld\n", posicao);
        exit(EXIT_FAILURE);
    }
    size_t sz = (size_t) posicao;
    
    unsigned char *buffer == malloc(sz);
    if (buffer == NULL && sz > 0) {
        printf("Cannot malloc %zu\n", sz);
        exit(EXIT_FAILURE);
    } 

    printf("Size %zu\n", sz);

    size_t read_count = fread(buffer, 1, sz, file);
    if (read_count != sz) {
        printf("Size mis-match %zu %zu\n", sz, read_count);
    } 
    for (size_t i = 0; i < read_count; i++) {
        printf("%x ", buffer[i]);
    }

    free(buffer);
    fclose(file);
  1. 检查文件是否在使用 fopen 后立即打开(如问题评论中所述)
  2. 使用fseek(file, 0, SEEK_END);
  3. 后将光标移动到文件开头
  4. 正确选择fread参数并得到它们的return值:
  • fread(buffer, 1, sizeof(buffer), file);。其中 sizeof(buffer) 是缓冲区的元素数。请参阅 @chux 的评论和回答 - 恢复 Monicasizeof(buffer) 如果缓冲区是动态分配的,则无法正常工作。
  • fread(buffer, sizeof(*buffer), sizeof(buffer), file);。使用 sizeof(*buffer).
  • 获取第一个元素的大小
  • fread(buffer, 1, posicao, file);。如果 posicao <= sizeof buffer.
  1. 访问缓冲区直到读取的字节数。
    for (size_t i = 0; i < readed; i++) printf("%x ", buffer[i]);。注意 @chux 所说的 fread return - 恢复 Monica(returns size_t 八字节类型)

代码:

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

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("Usage: Please insert the file to recover photos\n");
        return 1;
    }
    else
    {
        FILE *file;

        file = fopen(argv[1], "rb");

        //Cannot open file --> check pointer file after fopen
        if (file == NULL)
        {
            printf("Cannot open file \n");
            exit(0);
        }

        long posicao = ftell(file);

        printf("Ponteiro no Inicio %ld\n", posicao);

        fseek(file, 0, SEEK_END);

        posicao = ftell(file);

        rewind (file); // Sets the position indicator associated with stream to the beginning of the file

        unsigned char buffer[posição]; // o buffer deveria ser criado aqui depois de pegar a posição final

        printf("Ponteiro no Fim: %ld\n",posicao);

        // Read the content --> é sempre bom verificar o valor lido
        // o terceiro parâmetro estava 1, deveria ser a "posicao"
        size_t readed = fread(buffer, sizeof(buffer), posicao, file);

        for(size_t i = 0; i < readed; i++) // usar readed como limite
        {
            printf("%x ", buffer[i]); // prints a series of bytes
        }
    }
}

参考文献:

建议代码如下:

  1. 消除冗余代码
  2. 正确获取文件长度
  3. 正确声明输入缓冲区
  4. 正确读取文件
  5. 正确使用从文件读取的字节数来控制循环
  6. 没有检查它应该检查的所有错误

缓冲区的大小适合容纳整个文件,因此缓冲区不会溢出。这种溢出会导致段错误事件。

现在,建议的代码:

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

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("Usage: %s inputFileName\n Please insert the file to recover photos\n", argv[0]);
        return EXIT_FAILURE;
    }

    FILE file = fopen(argv[1], "rb");

    //Cannot open file
    if (file == NULL)
    {
        printf("Cannot open file \n"); // better to use perror()
        exit(0);  // 0 indicates success, better to use -1
    }       

    
    // move file pointer to end of file
    fseek(file, 0, SEEK_END);

    // get current file pointer location, relative to beginning of file
    long posicao = ftell(file);

    // move file pointer to start of file
    fseek(file, 0, SEEK_SET );
    
    printf("Ponteiro no Inicio %ld\n", posicao);

    // generate correct buffer size via a VLA (variable length array)
    unsigned char buffer[ posicao ];
    
    //Read the content and recover number of bytes read
    size_t bytesread = fread(buffer, sizeof(buffer), 1, file);

    // use number of bytes read as index limiter to display bytes
    for( size_t i = 0; i < bytesread; i++)
    {
        printf("%x ", buffer[i]); // prints a series of bytes
    }
}