【问题标题】:Reading "pure" bytes in C在 C 中读取“纯”字节
【发布时间】:2012-03-23 05:42:33
【问题描述】:

我想知道..您如何从二进制文件中一次读取一个字节?例如,我想从某个二进制文件中一次读取一个字节,然后将这些确切的字节写入某个输出文件(基本上是 cp 命令的一个非常基本的实现)。我当前的 C 代码如下所示:

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

int main(int argc, char**argv)
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
        return 1;
    }

    FILE *outfile;
    outfile = fopen(argv[1], "w");

    unsigned char c;
    char temp;
    int tracker = 0;
    // Use temp because unsigned char will never be EOF
    while ((temp = getchar()) != EOF) {
        c = (unsigned char) temp;
        fprintf(outfile, "%c", c);
    }
fclose(outfile);
return 0;
}

我这样运行程序:./main output.au &lt; sample.au(.au 是一个音频文件)

但是,我在output.au 文件中得到的只是一堆重复的“^@”。我可以正常播放sample.au 音频文件,但不能播放output.au。我还(有点毫无意义地)对这两个文件做了一个diff,正如预期的那样,它们的结果不同。

帮助? 谢谢! -kstruct

更新 感谢大家的回复.. 我的代码现在看起来像:

outfile = fopen(argv[1], "wb");

int c;
while ((c = getchar()) != EOF) {
    fprintf(outfile, "%c", c);
}

【问题讨论】:

  • 通常你会在 C 中读/写 pure 字节块,而不是单字节方法。
  • @kstruct 你更新的代码对我有用。

标签: c binary byte


【解决方案1】:

getchar() 返回一个int。 您将int 分配给char 类型的变量,从而丢失信息。 不要那样做。

temp 声明为 int,然后摆脱演员表。

【讨论】:

  • 我明白了,我同意一切。但是我似乎仍然遇到问题..我更新的代码在上面..帮助?谢谢!
  • 啊啊!您将输入从文件重定向到stdinstdin 是一个文本模式的流,并不适合你正在做的事情。无论如何...输入文件中有“^@”吗?
  • 不,输入文件是一堆乱七八糟的看起来像垃圾的东西。嗯,stdin 似乎在我直接执行 getchar() 后跟 fprintf 时有效,但似乎当我将c 存储到unsigned int[] 然后在其他时间写入数组时停止工作......想法?
  • Linux 中的文本模式和二进制模式流之间应该没有区别(您显然正在使用)。至于通过unsigned int[] 传递数据时的行为变化,我不知道...... 它是如何“停止工作”的?
【解决方案2】:

有几件事需要解决: 1) 以二进制形式重新打开 STDIN。 freopen(NULL, "rb", stdin); 2) 打开输出文件为: fopen(argv[1], "wb"); 3) temp 需要是 int 类型。

【讨论】:

  • 根据the C99 Standard“由实现定义允许更改模式(如果有的话),以及在什么情况下。”
  • 鉴于他不要求的条件,他在 UNIX 上。
【解决方案3】:

进行以下更正:

- outfile = fopen(argv[1], "w");
+ outfile = fopen(argv[1], "wb");


- c = (unsigned char) temp;
+ c = (unsigned char) (char) temp;

【讨论】:

  • c 已经是char,新的演员阵容没用。正如pmg上面所说,c应该是int,但我认为即使在这种情况下也不需要通过char进行转换。
  • 他修复了一个字符后就不是字符了。在同一演员表上缩小和更改签名时,我被烧了几次。
  • getchar 返回,如果不是 EOF,则将 unsigned char 转换为 int。反过来应该可以。
  • 好点。如果 temp 永远不能为负数,则只需要一次强制转换。
猜你喜欢
  • 2012-10-04
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 2011-07-01
  • 2014-04-23
相关资源
最近更新 更多