我试图制作一个C文件,该文件打开一个文件,并使用每个字节的十六进制格式(%02x)逐字节打印其文件。
结果应该是这样的:
$ ./hexabyte file
43
3d
67
...
我知道我想使用fread来做到这一点,但是我不确定为什么该解决方案不起作用:
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
int args_test(int args, char path[]){
if(args < 1){
fprintf(stderr, "Usage: %s path\n", path);
exit(EXIT_SUCCESS);
}
if(args < 2){
fprintf(stderr, "Usage: %s path\n", path);
exit(EXIT_SUCCESS);
}
if(args > 2){
fprintf(stderr, "Usage: %s path\n", path);
exit(EXIT_SUCCESS);
}
return 0;
}
int open_file(char path[]){
FILE *fp;
fp = fopen(path, "r");
char buffer[1000];
if(!fp){
fprintf(stderr, "%s\n", strerror(errno));
return EXIT_FAILURE;
}
fseek(fp, 0, SEEK_END);
int len = ftell(fp);
//Why does it not reach this loop?
while (fread(buffer, strlen(path), 1, fp) == 1){
printf("%02x hexabytes\n", len);
}
fclose(fp);
exit(EXIT_SUCCESS);
}
int main(int args, char* argv[]){
if(args < 2 || args > 2){
args_test(args, argv[0]);
}
args_test(args, argv[1]);
open_file(argv[1]);
exit(EXIT_SUCCESS);
}
似乎它从未到达我的while循环,因此也从不打印任何内容
答案 0 :(得分:1)
您需要将文件指针重置为文件的开头:
fseek(fp, 0, SEEK_SET);
答案 1 :(得分:1)
您要搜索文件的末尾,因此fread
将没有任何内容可读取。您需要重新开始。
fread
也被要求读取路径的长度,这似乎是错误的,您的循环设置方式似乎是一次仅1个字节。
fseek(fp, 0, SEEK_END); // Seeks to end of file
int len = ftell(fp);
// Nothing to read, at end
while (fread(buffer, strlen(path), 1, fp) == 1){
printf("%02x hexabytes\n", len);
}
在ftell
之后再次寻求。
fseek(fp, 0, SEEK_END); // Seeks to end of file
int len = ftell(fp);
fseek(fp, 0, SEEK_SET); // Go to start again
// Read from start, 1 byte at a time
char byte;
while (fread(&byte, 1, 1, fp) == 1){
printf("%02X\n", (int)byte);
}
您也可以一次读取1000个字节(如buffer
一样),但是随后需要第二个循环,或者可以读取整个文件,但是需要动态分配缓冲区({{1 }}。
答案 2 :(得分:1)
即使您解决了fseek
问题,也遇到了其他问题:
while (fread(buffer, strlen(path), 1, fp) == 1){
printf("%02x hexabytes\n", len);
}
请注意,您不会一次读取一个字节;而是一次读取一个字节。您一次读取的是strlen(path)
大小的块中的字节。
您也不打印刚刚读取的字节;您正在打印文件的长度。因此,假设您的文件大小为65536字节,您将获得输出
10000 hexabytes
10000 hexabytes
10000 hexabytes
...
65536 / strlen(path)
次。我认为那不是你想要的。
我认为您要追求的是这些方面的更多东西:
unsigned char buffer[1000]; // for arbitrary bytes, unsigned char works better.
int bytes_read = 0;
while ( (bytes_read = fread( buffer, 1, sizeof buffer, fp )) != EOF )
{
for( int b = 0; b < bytes_read; b++ )
{
printf( "%02hhx\n", buffer[b] ); // %x expects unsigned *int*, use the
} // hh modifier to specify unsigned char
}
表达式
bytes_read = fread( buffer, 1, sizeof buffer, fp )
从sizeof buffer
读取多达fp
(在这种情况下为1000)字节,并将实际读取的数字存储到bytes_read
。如果我们没有击中EOF
,那么我们将打印buffer
的内容。