[剧透:CS50]:初始化为44时,为什么sizeof(HEADER_SIZE) = 4?

问题描述 投票:0回答:1

下面给出的是我对CS50第4周:卷的解决方案。我试图解决的问题是读取 .wav 文件并根据命令行参数“factor”更改其音量。

问题: 当我测试这段代码时,我最初使用

fread(header, HEADER_SIZE, 1, input);
我的代码编译时不会出现错误,并且会生成以下输出文件:
./volume input.wav output.wav 1.0

但是,如果我将体积因子更改为 1.0 以外的任何其他值,则会生成损坏的输出文件。

// 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;

void copy_header(FILE *input, FILE *output);
void copy_samples(FILE *input, FILE *output, float factor);

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");
        return 1;
    }

    float factor = atof(argv[3]);

    copy_header(input, output);
    copy_samples(input, output, factor);

    // Close files
    fclose(input);
    fclose(output);
}

void copy_header(FILE *input, FILE *output)
    {
        uint8_t header[HEADER_SIZE];

        fread(header, sizeof(HEADER_SIZE), 1, input);
        fwrite(header, sizeof(HEADER_SIZE), 1, output);
        printf("header: %s; header_size: %lu; HEADER_s: %lu\n", header, sizeof(header), sizeof(HEADER_SIZE));
    }

void copy_samples(FILE *input, FILE *output, float factor)
{
    int16_t buffer;

    while (fread(&buffer, sizeof(int16_t), 1, input) != 0)
    {
        buffer = buffer * factor;
        fwrite(&buffer, sizeof(int16_t), 1, output);
    }
}

经过大量挖掘,我发现输出为:

printf("header: %s; header_size: %lu; HEADER_s: %lu\n", header, sizeof(header), sizeof(HEADER_SIZE)); 
将会是:

header: RIFFDb; header_size: 44; HEADER_s: 4

为什么sizeof(HEADER_SIZE)的值变成了4?我在这里完全错过了什么吗?我处理这个问题的方法正确吗?

我使用以下方法修复了代码中的错误:

fread(header, sizeof(header), 1, input);

但我想知道我为什么以及如何破解这段代码。预先感谢!

c cs50
1个回答
0
投票

当查看这些行时:

    uint8_t header[HEADER_SIZE];

    fread(header, sizeof(HEADER_SIZE), 1, input);
    fwrite(header, sizeof(HEADER_SIZE), 1, output);

您似乎有这样的印象:在声明

header
之后,
HEADER_SIZE
现在与
header
的大小相关联。 事实并非如此。

sizeof
运算符计算其操作数的大小(以字节为单位)。 在
sizeof(HEADER_SIZE)
的情况下,操作数是类型为
HEADER_SIZE
的变量
int
(或更准确地说,括号内的变量)。 其计算结果为 4,因为
int
在您的系统上占用 4 个字节。

这会导致代码出现问题,因为仅读取 4 个字节,而不是您预期的 44 个字节。

这有效:

fread(header, sizeof(header), 1, input);

因为

sizeof(header)
给出了
header
数组的大小(以字节为单位),即 44。

这也可以:

fread(header, HEADER_SIZE, 1, input);

因为它将传入 44 作为要读取的字节数。

© www.soinside.com 2019 - 2024. All rights reserved.