更改CS50文件卷的Lab4代码:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
const int HEADER_SIZE = 44;
uint8_t header[HEADER_SIZE];
int16_t buffer;
int main(int argc, char *argv[])
{
// Check command-line arguments
if (argc != 4)
{
printf("Usage: ./volume input.wav output.wav factor\n");
return 1;
}
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
FILE *output = fopen(argv[2], "w");
if (output == NULL)
{
printf("Could not open file.\n");
return 1;
}
float factor = atof(argv[3]);
fread(header, 1, HEADER_SIZE, input);
fwrite(header, 1, HEADER_SIZE, output);
int n = 0; // for debug purpose
while (fread(&buffer, 2, 1, input))
{
buffer = buffer * (float)factor;
fwrite(&buffer, 2, 1, output);
if (n == 2115) // for debug purpose
{
if (n == 2111) // for debug purpose
;
}
printf("%d\n", n++); // for debug purpose
}
// Close files
fclose(input);
fclose(output);
}
问题是..。它在CS50代码空间IDE中完美地工作:

但是,我所有的本地编译器(我尝试过: bcc32、cpp32、tcc、gcc、clang)都给出了相同的结果--这个破文件的输出(必须是345 kb文件,但它是5kb):https://cdn.discordapp.com/attachments/792992622196424725/964833387363852308/output.wav
我尝试过一些调试:

根据调试,它总是在2117步(4608缓冲区值)停止。
我想再次指出,在CS50 IDE中,它工作正常,并且贯穿了所有176399步:)

feof(输入)和feof()调试:

请帮助解决这个难题!我不能休息,直到我明白那里出了什么问题。
发布于 2022-04-17 04:54:27
在Windows上,您必须使用模式rb (或用于写入的wb )打开二进制文件。在Unix上,为了可移植性,您应该这样做,但在实践中,无论哪种方式,它都能工作。(这与编译器无关)。
原因是在文本文件中,Windows将值为0x1A (Ctl)的字节视为EOF指示符。Unix不这样做;在Unix上,文件的末尾是文件结束的地方。
此外,Windows使用两个字符的行尾指示符(\r\n),该指示符必须转换为单个\n,因为C标准要求将文本文件中的多字符行结束指示符转换为单个换行符(并在写入文件时返回)。这在Unix上也不会发生,因为Unix行尾已经是一个换行符了。
因此,在Windows上,如果您读取二进制文件而不指定b换二进制打开模式,那么读取将在文件的第一个0x1A处停止。在您的例子中,这似乎发生在2117字符读,但请注意,这可能不是文件中的2117字符,因为换行符翻译。您可以尝试使用二进制编辑器查看您的文件,但底线是,如果您认为您的程序可能在Windows下运行,那么您应该始终对二进制文件使用rb和wb。Unix会忽略b,并告诉它停止处理文件。
https://stackoverflow.com/questions/71897311
复制相似问题