C

时间:2016-04-28 06:39:16

标签: c ruby file binary integer

我正在尝试将一些简单的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抽象的基本概念,如字节尺寸或其他对我来说不明显的东西。此时的输出完全不同。

在我向右迈出这一步之后,目标就是从中产生一个基于整数的值。

了解为什么输出不准确的任何线索都非常感谢!

1 个答案:

答案 0 :(得分:1)

    在输入函数指示读取失败后,应

    feof()使用。它区分了失败是否归因于文件结束。

  1. strlen()报告字符串长度(不包括空字符)。在C中,字符串是一系列字符,包括空字符。不要使用它来确定缓冲区中有多少字节。使用fread()的返回值。 @subin

  2. 检查输入功能的返回值。 @user694733

  3. 避免使用非格式字符串的字符串作为printf()的第一个参数。

  4. 最好使用unsigned 1u进行位操作。

  5. 轻微:避免使用像CHAR_BIT这样的幻数。<limit.h>

  6. 轻微:使用fclose()完成后将玩具放好。

  7.   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);