c语言 - 标头的 fread() 函数中 pset4 实验室'volume'的解决方案视频中可能存在错误



这是Brian在cs50 week4 lab4中解释的代码

// Modifies the volume of an audio file
#include <stdint.h>
#include <stdio.h>
#include <stdlib.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 factorn");
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");
return 1;
}
float factor = atof(argv[3]);
// TODO: Copy header from input file to output file
uint8_t header[HEADER_SIZE];
fread(header, HEADER_SIZE, 1,input))

fwrite(header,HEADER_SIZE, 1, output);

// TODO: Read samples from input file and write updated data to output file
int16_t buffer;
while(fread(&buffer, sizeof(int16_t), 1, input))
{
buffer *= factor;       
fwrite(&buffer, sizeof(int16_t ), 1 ,output);
}
// Close files
fclose(input);
fclose(output);
}

我对什么是fread()和fwrite()感到困惑。它说:

while(fread(header, HEADER_SIZE, 1, input))

不应该是:

while(fread(header,sizeof(uint8_t), HEADER_SIZE, input)) 

因为语法是:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

ptr,这是要读取数据的内存的地址(第一个字节),

size,这是要读取的数据类型的大小(以字节为单位),

nmemb,这是一次读取的类型的数量,和

流,它是指向fopen返回的FILE的指针。

为什么我们在fwrite()和fread()中使用缓冲区的地址,而不是在fwrite()和fread()中使用header地址?缓冲区的值会在每次循环后被覆盖吗?

看情况。

如果你想接收一个完整的报头,然后把它作为一个报头来处理,带有报头的各个部分的含义,那么你应该请求一个你想要处理的报头的副本:

fread(header, HEADER_SIZE, 1, input)

如果你想接收一些字节(恰好是头的大小),然后将它们作为单独的字节处理(即忽略它们一起构成头的事实),那么你应该请求许多字节:

fread(header,sizeof(uint8_t), HEADER_SIZE, input)

(经明确许可,我添加了WeatherVance的贡献。它为我试图解释语义的方法增加了技术结果的细节。

fread(header, 1, 44, input)fread(header, 44, 1, input)都将尝试读取44字节。
如果只能读取2个字节,那么fread将在第一种情况下返回2,在第二种情况下返回0。因为第一个程序试图读取44个大小为1的元素,第二个程序想读取1个大小为44的元素

相关内容