【问题标题】:Bynary/Integer representation of file in CC中文件的二进制/整数表示
【发布时间】:2016-08-22 18:30:08
【问题描述】:

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

在我正确完成这一步之后,目标是从中生成一个基于整数的值。

非常感谢任何有助于理解为什么该输出不准确的线索!

【问题讨论】:

  • 首先你需要find a good beginners book in C并学习它。那么你应该阅读Why is “while ( !feof (file) )” always wrong?
  • const size_t len = strlen(buffer); 不能用于二进制。 strlen 仅适用于 C 字符串。 BTW读取函数返回成功读取字节的元素总数
  • 一般来说,如果可以使用十六进制打印,请使用带有 %x 的 printf()。你不能在这里可靠地使用 strlen() 。成功时, fread() 和 fwrite() 返回读取或写入的项目数。此数字等于仅当 size 为 1 时传输的字节数。因此使用返回值而不是 strlen()
  • 您没有检查文件函数的返回值。 C 中的错误检查是至关重要的,否则如果出现问题,您将得到未定义的行为

标签: c ruby file binary integer


【解决方案1】:
  1. feof() 应该在输入函数指示读取失败后使用。它会区分失败是否是由于文件结束造成的。

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

  3. 检查输入函数的返回值。 @user694733

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

  5. 最好将unsigned1u 一起用于位操作。

  6. 次要:避免像 7 这样的幻数。CHAR_BIT&lt;limit.h&gt; 中可用。

  7. 未成年人:使用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);

【讨论】:

    猜你喜欢
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 2018-03-17
    • 2014-06-10
    • 2016-02-20
    • 1970-01-01
    • 2020-12-11
    相关资源
    最近更新 更多