【问题标题】:C: WAV file not being opened in "rb"C:WAV文件未在“rb”中打开
【发布时间】:2017-12-12 07:41:13
【问题描述】:

我在尝试打开 WAV 文件进行阅读时遇到了困难。当我编译并运行我的代码时,我没有收到任何错误。我正在添加我正在弄乱的代码(假设已经调用了必要的库)。该程序应该显示 WAV 文件的内容,尽管我输入了有效的文件名和扩展名,但语句“无效文件名。再试一次”。仍在打印到屏幕上。我尝试的另一种方法是输入文件的目录而不仅仅是名称,当我这样做时,我的程序结束并且没有显示任何内容。任何指导都会有所帮助,并提前感谢您!

main(){
FILE *fin;
printf("\nEnter filename of WAV file: \n");
char filename[256];
scanf("%s",&filename);
fin = fopen(filename,"rb"); // opens in rb

if(!fin) // if file doesn't exist
{
printf("Invalid filename. Try again.\n");
}
else // if fin opens succesfully
{
    printf("\nFile opened succesfully\n");

    char *header;
    header = (char *)malloc(44);
    if(header == NULL)
    {
        printf("Error in allocating memory.");
        return 0;
    }


    fread(header,1,44,fin);

    char *chunkid;
    unsigned int *chunksize;
    char *format;
    char *subchunk1id;
    unsigned int *subchunk1size;
    unsigned short int *audioformat;
    unsigned short int *numchannels;
    unsigned int *samplerate;
    unsigned int *byterate;
    unsigned short int *blockalign;
    unsigned short int *bitspersample;
    char *subchunk2id;
    unsigned int *subchunk2size;
    unsigned int *data;

    chunkid = header;
    chunksize = (unsigned int *)(header + 4);
    format = header + 8;
    subchunk1id = header + 12;
    subchunk1size = (unsigned int *)(header + 16);
    audioformat = (unsigned short int *)(header + 18);
    numchannels = (unsigned short int*)(header + 20);
    samplerate = (unsigned int*)(header + 24);
    byterate = (unsigned int*)(header + 28);
    blockalign = (unsigned short int*)(header + 30);
    bitspersample = (unsigned short int*)(header + 32);
    subchunk2id = header + 36;
    subchunk2size = (unsigned int*)(header + 40);
    data = (unsigned int*)(header + 44);

    printf("\n%c%c%c%c",*(header),*(header+1),*(header+2),*(header+3));
    printf("\n%d",*chunksize);
    printf("\n%c%c%c%c",*(header + 8),*(header + 9), *(header + 10), *(header + 11));
    printf("\n%c%c%c%c",*(header + 12),*(header + 13), *(header + 14), *(header + 15));
    printf("\n%d",*subchunk1size);
    printf("\n%d",*audioformat);
    printf("\n%d",*numchannels);
    printf("\n%d",*samplerate);
    printf("\n%d",*byterate);
    printf("\n%d",*blockalign);
    printf("\n%d",*bitspersample);
    printf("\n%c%c%c%c",*(header + 36),*(header + 37),*(header + 38), *(header + 39));
    printf("\n%d",*subchunk2size);
    printf("\n%d",*data);


    fclose(fin);

} // end of else
} // end of main

【问题讨论】:

  • 您的右大括号 (}) 至少比左大括号 ({) 多。
  • 不确定您使用的是什么编译器,但gcc 在您的scanf 行报告了一个警告:warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[256]’ [-Wformat=] scanf("%s", &filename);
  • 哦,我明白了。将scanf("%255s",&filename); 更改为scanf("%255s",filename);。您需要将字符串持有者的第一个字节的地址作为参数发送给scanf(),而不是指向该地址的指针
  • numchannels = (unsigned short int*)(header + 20); 违反了strict aliasing。您不能确定header + 20unsigned short 的有效地址。 “它适用于我的系统”并没有改变它是未定义行为的事实。
  • 您使用的是什么操作系统和编译器?

标签: c file audio binary wav


【解决方案1】:

尝试使用

if(!fin)
{
  perror("Error:");
}

它将打印正确的错误消息,以便您轻松诊断文件无法打开的原因。可能是您的程序找不到您指定的文件,或者您可能没有打开它的权限。 Here 是您在打开文件时可能遇到的错误列表。

我可以看到的另一个可能的问题是您正在使用scanf 从标准输入读取到您的字符数组。如果您指定的路径包含空格怎么办?每个单词后跟一个空格将被视为不同的字符串。而且你只会得到第一个最长的不包含空格的单词。因此,您的程序并未读取整个路径。你可以试试 scanf("%[^\n]", filename) 将一直读取,直到遇到 '\n'。谨防!这使您面临缓冲区溢出的可能性,如果您将一个长度大于 256 的有效字符串集传递给程序,那么您的写入将超出 char 数组的边界,这是不好的。所以尝试scanf("%255[^\n]", filename) 或尝试使用fgets() doc SO 提供缓冲区溢出保护。

【讨论】:

  • 问题是找不到文件。这帮助我弄清楚了,谢谢!
【解决方案2】:

在编译代码时使用警告会暴露你的错误。

改进建议,将标头描述为如下结构:

typedef struct  
{
    char    riff_tag[4];
    int32_t riff_length;
    char    wave_tag[4];
    char    fmt_tag[4];
    int32_t fmt_length;
    int16_t audio_format;
    int16_t num_channels;
    int32_t sample_rate;
    int32_t byte_rate;
    int16_t block_align;
    int16_t bits_per_sample;
    char    data_tag[4];
    int32_t data_length;
}waveFileHeader, *waveFileHeaderptr ;

并像这样阅读:

waveFileHeaderptr header =malloc ( sizeof (waveFileHeader));
fread (header , sizeof (waveFileHeader), 1 , fin);

将使以下代码和处理不那么混乱

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多