CS50 WAV音量调节程序check50检测超时问题求助
CS50 Volume程序超时问题解决方案
你的代码核心问题出在while循环的条件判断,导致程序进入死循环,最终触发check50的超时检测。
问题分析
fread函数的返回值是成功读取的元素个数(而非EOF):
- 当请求读取1个
int16_t元素时,成功读取返回1,到达文件末尾或读取失败返回0。 - EOF是一个有符号整数(通常为-1),而
fread返回的size_t是无符号类型。将无符号的返回值和有符号的EOF比较时,会发生隐式类型转换,导致0 != EOF的判断永远为真,循环无法终止,程序一直运行直到超时。
修复后的代码
#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // Number of bytes in .wav header const int HEADER_SIZE = 44; int main(int argc, char *argv[]) { // Check command-line arguments if (argc != 4) { printf("Usage: ./volume input.wav output.wav factor\n"); return 1; } // Open files and determine scaling factor 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"); fclose(input); // 打开输出失败时先关闭输入文件,避免资源泄漏 return 1; } float factor = atof(argv[3]); // 用uint8_t存储header更合理,因为header是字节流而非16位整数数组 uint8_t header[HEADER_SIZE]; fread(header, HEADER_SIZE, 1, input); fwrite(header, HEADER_SIZE, 1, output); int16_t sample; // 正确判断:当成功读取1个元素时继续循环 while (fread(&sample, sizeof(int16_t), 1, input) == 1) { sample = sample * factor; fwrite(&sample, sizeof(int16_t), 1, output); } fclose(input); fclose(output); }
额外优化说明
- 打开输出文件失败时,先关闭已打开的输入文件,避免资源泄漏。
- 使用
uint8_t数组存储WAV头,因为WAV头是由单个字节组成的结构,而非连续的16位整数,这样更符合数据的实际格式。
内容的提问来源于stack exchange,提问作者abdul
相关产品推荐
相关产品推荐

