在C中一次读取16个字节的文件

时间:2014-10-16 19:44:41

标签: c file hex offset

我试图一次读取一个16字节的命令行参数解析的文件。我将字节存储在unsigned char数组中。然后我尝试以HEX格式打印元素,然后,如果它们是可打印字符,我打印它们,如果不是,我打印一个点"。"我还想在每个新行上打印文件开头的字节偏移量,但我想在开始处理之前让其余部分工作。我遇到的问题是我正在阅读的文件不是打印所以我不认为我做得对。我开始使用fread(),但我想我可能需要使用fseek(),但我不确定。如果有人能指出我正确的方向或告诉我,如果我做错了什么我会很感激。

代码:

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

int main(int argc, char *argv[])
{
    FILE *fp;

    int i, j;

    unsigned char buffer[17];

    fp = fopen(argv[1], "r");

    while(!feof(fp))
    {
        while(fread(buffer, 16, 1, fp) !=0)
        {

            for(i=0; i < 16; i++)
            {
                printf("%X ", buffer[i]);
            }

            for(j = 0; j < 16; j++)
            {
                if(isprint(buffer[j]))
                    printf("%s", buffer[j]);
                else
                    printf("." );
            }

            printf("\n");
        }
    }

    fclose(fp);

    return 0;
}

预期产出:

0001:  40 4F 28 37 0B B8 FF 9D 81 5E 2E 73 B5 CC 6A 70 @O(7.....^.s..jp
0010: 0F 30 9C 6E 7E F7 53 E0 C1 5E 9A 38 C5 02 F2 33 .0.n .S..^.8...3

编辑:修复了建议的问题。是以文本模式而不是二进制文件打开文件。将读取模式更改为"rb",代码现在正常工作。

1 个答案:

答案 0 :(得分:4)

您需要以二进制模式打开文件,在文本模式下使用fseek / ftell文件会产生不稳定的值。

所以用

打开文件
fp = fopen(argv[1], "rb");

同样好的做法是始终通过检查返回值来检查函数是否成功,在本例中为if (fp != NULL) ...

而不是读取16个字节的块读取1个字节16次,否则如果文件长度不能均匀分割为16,则错过最后一个字节

if ( fp != NULL )
{
  int read = 0;
  while((read = fread(buffer, 1, 16, fp)) > 0)
  {
    for(i=0; i < read; i++)
    {
    ...
  }
  fclose(fp);
}

我不需要外while (feof(fp)) ...

in

printf("%s", buffer[j]);

你没有使用正确的格式说明符,缓冲区[j]是一个字符,而不是一个字符串所以写

printf("%c", buffer[j]);

编辑:如果你不是在一些嵌入式环境中,一次只读取16个字节的堆栈,那么你可以读取2k或更大的尺寸以便更快地读取。

相关问题