我正在尝试将一些简单的Ruby代码移植到C语言中以提高速度,但由于C不是我的主要语言而无法实现,因此我很难理解导致它的原因。以下是Ruby中的代码,以明确目的:
source_file = open("/tmp/image.jpg")
content = source_file.read
content_binary_string = content.unpack("b*")[0]
content_integer = content_binary_string.to_i(2)
然后我在C中进行了几次尝试以获得相同的结果,不知怎的,我坚持使用Ruby和C输出之间的二进制比较。这是我到目前为止所获得的C代码:
// gcc -Wall -Wextra -std=c99 xxd.c
#include <stdio.h>
#include <string.h>
int main() {
char buffer[32];
FILE *image;
image = fopen("/tmp/image.jpg","rb");
while (!feof(image)) {
fread(buffer, sizeof(buffer), 1, image);
const size_t len = strlen(buffer);
for (size_t j = 0; j < len; j++ ) {
for (int i = 7; i >= 0; i--) {
printf(buffer[j] & (1 << i) ? "1" : "0");
}
}
}
return 0;
}
请注意,C代码尚未完成,我现在打印二进制值,因此我可以将输出与当前工作代码进行比较,我相信我缺少一些由Ruby抽象的基本概念,如字节尺寸或其他对我来说不明显的东西。此时的输出完全不同。
在我向右迈出这一步之后,目标就是从中产生一个基于整数的值。
了解为什么输出不准确的任何线索都非常感谢!
答案 0 :(得分:1)
feof()
使用。它区分了失败是否归因于文件结束。
strlen()
报告字符串的长度(不包括空字符)。在C中,字符串是一系列字符,包括空字符。不要使用它来确定缓冲区中有多少字节。使用fread()
的返回值。 @subin
检查输入功能的返回值。 @user694733
避免使用非格式字符串的字符串作为printf()
的第一个参数。
最好使用unsigned
1u
进行位操作。
轻微:避免使用像CHAR_BIT
这样的幻数。<limit.h>
。
轻微:使用fclose()
完成后将玩具放好。
image = fopen("/tmp/image.jpg","rb");
if (image == NULL) Handle_OpenFailure();
size_t count;
while ((count = fread(buffer, sizeof buffer[0], sizeof buffer, image)) > 0) {
for (size_t j = 0; j < count; j++ ) {
for (int i = CHAR_BIT-1; i >= 0; i--) {
fputc(buffer[j] & (1u << i) ? '1' : '0', stdout);
}
}
}
fclose(image);