在C中复制文件似乎不完全工作

bqjvbblv  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(144)

在我的编程课程中,我必须编写一个复制文件的程序。
此程序要求以下内容:

  • 命令提示符中的输入文件
  • 输出文件的名称

需要复制的文件是.WAV音频文件。我用3秒的音频样本试过这个。
问题是我确实得到了一个文件,因为它是空的。

while((ch = fgetc(input)) != EOF)
{
  fputc(ch, output);
}

我希望有人能指出我可能犯了一些初学者的错误。

nimxete2

nimxete21#

如果满足所有先决条件,那么你展示的while循环原则上应该可以工作:

  • 文件可以打开。
  • 如果在Microsoft操作系统上,则文件以二进制模式打开(请参见下文)。
  • ch是整数。

换句话说,您遇到的所有问题都在此代码之外。

二进制模式:CR-LF问题

post解释了使用回车/换行组合的可能原因;最后,这是很自然的事,因为打字机和电传打字机是两种截然不同的操作:你移动大杠杆上的 * 滑架 * 旋转 * 压纸辊 * 或 * 汽缸 * 一个指定的度数,使下一行不会打印在前一行;这就是恰当命名的 * 换行。* 只有在这时,使用同一个控制杆,您才可以移动回车,使水平打印位置位于行的开头。这就是恰当命名的 * 回车。* 事件的顺序只是一个技术细节。
DOS C实现试图变得更智能:一个从Unix移植来的C程序可能会产生只有换行符的文本;输出例程将透明地添加回车符,以使其遵循DOS约定并正确打印。2相应地,输入文件中的CR/LF组合在被标准库实现读取时将被无声地转换为仅LF。
DOS文件约定也使用CTR-Z(26)作为文件结束标记。同样,这可能是一个有用的提示,打印机当前作业的所有数据都已收到。
不幸的是,这些约定被作为默认行为,并且在今天通常是令人讨厌的:没有人再向打印机发送纯文本了(除了三个人谁会在这篇文章下评论说,他们仍然这样做)。
这是一个麻烦,因为对于非纯文本文件,静默数据更改是灾难性的,必须抑制,在fopen模式参数中传递的b“标志”指示“二进制”数据:要忠实地阅读,您必须指定fopen(filename, "rb");要忠实地书写,您必须指定fopen(filename, "wb")

空文件!?

当我试图复制一个没有二进制标志的wave文件时,数据被以所描述的方式改变,并且复制在源文件中第一个值为26(CTRL-Z)的字节之前停止。换句话说,虽然副本被损坏,但它不是空的。顺便说一下,所有的wave文件都以字节RIFF开始,所以在第一个位置不会遇到CTRL-Z。
空目标文件有多种可能性,最有可能的是:

  • 你没有发出或错过了一个关于打开文件的错误信息(你的编辑器是否锁定了输出?),当一个文件指针为空时,程序崩溃了。注意,当你在标准输出上输出错误时,错误信息可能无法打印出来:该流被缓冲,并且缓冲的输出可能在崩溃时丢失。相反,输出到stderr是不缓冲的,以防止消息丢失。
  • 您正在查看错误的输出文件。这种错误非常常见。您可以通过删除正在查看的文件或在开始复制之前手动打印某些内容来执行健全性检查。

通常,检查 every 操作的返回值(包括fputc!)。

相关问题