在我的编程课程中,我必须编写一个复制文件的程序。此程序要求以下内容:
需要复制的文件是.WAV音频文件。我用3秒的音频样本试过这个。问题是我确实得到了一个文件,因为它是空的。
.WAV
while((ch = fgetc(input)) != EOF) { fputc(ch, output); }
我希望有人能指出我可能犯了一些初学者的错误。
nimxete21#
如果满足所有先决条件,那么你展示的while循环原则上应该可以工作:
ch
换句话说,您遇到的所有问题都在此代码之外。
post解释了使用回车/换行组合的可能原因;最后,这是很自然的事,因为打字机和电传打字机是两种截然不同的操作:你移动大杠杆上的 * 滑架 * 旋转 * 压纸辊 * 或 * 汽缸 * 一个指定的度数,使下一行不会打印在前一行;这就是恰当命名的 * 换行。* 只有在这时,使用同一个控制杆,您才可以移动回车,使水平打印位置位于行的开头。这就是恰当命名的 * 回车。* 事件的顺序只是一个技术细节。DOS C实现试图变得更智能:一个从Unix移植来的C程序可能会产生只有换行符的文本;输出例程将透明地添加回车符,以使其遵循DOS约定并正确打印。2相应地,输入文件中的CR/LF组合在被标准库实现读取时将被无声地转换为仅LF。DOS文件约定也使用CTR-Z(26)作为文件结束标记。同样,这可能是一个有用的提示,打印机当前作业的所有数据都已收到。不幸的是,这些约定被作为默认行为,并且在今天通常是令人讨厌的:没有人再向打印机发送纯文本了(除了三个人谁会在这篇文章下评论说,他们仍然这样做)。这是一个麻烦,因为对于非纯文本文件,静默数据更改是灾难性的,必须抑制,在fopen模式参数中传递的b“标志”指示“二进制”数据:要忠实地阅读,您必须指定fopen(filename, "rb");要忠实地书写,您必须指定fopen(filename, "wb")。
fopen
b
fopen(filename, "rb")
fopen(filename, "wb")
当我试图复制一个没有二进制标志的wave文件时,数据被以所描述的方式改变,并且复制在源文件中第一个值为26(CTRL-Z)的字节之前停止。换句话说,虽然副本被损坏,但它不是空的。顺便说一下,所有的wave文件都以字节RIFF开始,所以在第一个位置不会遇到CTRL-Z。空目标文件有多种可能性,最有可能的是:
通常,检查 every 操作的返回值(包括fputc!)。
fputc
1条答案
按热度按时间nimxete21#
如果满足所有先决条件,那么你展示的while循环原则上应该可以工作:
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。
空目标文件有多种可能性,最有可能的是:
通常,检查 every 操作的返回值(包括
fputc
!)。