复制音频文件,发出指针问题

时间:2017-03-30 04:44:45

标签: c pointers fwrite fread

我想知道是否有人可以帮助我解决我遇到的问题。我非常确定这是一个指针问题(阅读:我非常非常C初学者),但我一直在努力解决这个问题并且一直无法修复问题(尽管阅读参考页面)。

我的代码是使用两个函数复制.WAV文件(函数原型是固定的)。首先它读取文件,然后使用旧文件中的数据样本写入新文件。标题在" R_WAV.h"中定义。作为typedef结构。代码运行于:

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#include "R_WAV.h"

//Function Declarations
int read_WAV(header_type *header, char **data, char *filename);
int write_WAV(header_type *header, char *data, char *filename);

int main()
{
    //Run read_WAV
    {
        header_type *header;
        char *filename[] = {//Various files};
        char **data;
        read_WAV(header, data, *filename);
    }
    //Run write_WAV
    {
        header_type *header;
        char *filename[] = {//Various files};   
        char *data;
        write_WAV(header, data, *filename);
    }

    //Run read_WAV again on new files to ensure header info is valid
    {
    header_type *header;
    char *filename[] = {//output files from write};
    char *data;
    read_WAV(header, data, *filename);
    }

    return(0);
}

我写的read_WAV函数(略有缩写)是:

int read_WAV(header_type *header, char **data, char *filename)
{   

    unsigned char   buffer4[4];
    unsigned char   buffer2[2];

    FILE    *fp = fopen(filename, "rb");    //Open file

    //Code here that checks if file successfully opened

    //If file valid, find length of file
    fseek(fp, 0L, SEEK_END);    //Place position at EoF
    int size = ftell(fp);       //Read the current value
    rewind(fp);                 //Reset position

    //Code here that checks if file size < min. header size, if true exits

    header = (void*)malloc(size);

    //Reading RIFF string
    fread(header->ChunkID, sizeof(header->ChunkID), 1, fp);
    printf("\nChunkID: %s \n", (header->ChunkID));  

等等,直到有时间阅读数据:

//Read DATA samples
char *buffer_data = (char*)malloc(header->Subchunk2Size);    
fread(buffer_data,1,(header->Subchunk2Size),fp);

//Error checking code here for if buffer==NULL

*data = buffer_data;

fclose(fp);
return(1);
}

write_WAV函数是:

int write_WAV(header_type *header, char *data, char *filename)
{
    char n_file[50];                            //Init. for new filename    
    int data_size = header->Subchunk2Size;      //Hold size of data chunk

    //CODE TO ALTER FILENAME (working properly)

    //Open new file (COPY_of_filename)
    FILE * fp_w = fopen(n_file, "wb");

    //Check to see if file was successfully created
    if (fp_w==NULL)
    {
        printf("\nUnable to create file.");
        return(-1);
    }

    //Write header to new file (first 44 bytes)
    fwrite(header, 1, 44, fp_w);

    //Write data to new file
    fwrite(data, 1, data_size, fp_w);
fclose(fp_w);
return (1);

}

我遇到两个主要问题:

1)如果我打开该函数中的一个.WAV文件,我只能在write_WAV()中正确写入头信息(前44个字节),然后使用fread和缓冲区来存储它。是否必须这样做?是否有另一种方法可以使用* header导致可以从read_WAV()访问此数据,而无需在write_WAV()中重新打开旧文件?

2)我无法正确复制数据样本。即使我在上面的标题中读取(并检查标题信息是否正确),我得到的只是打开新文件时的损坏噪音。我一直试图研究这个问题,但我一无所获。有人可以帮助解释/指出我所做的错误,以及我需要做些什么来解决它们?

我知道这很简单,我希望我的大脑能够自行解决问题。就像我说的那样,我已经阅读了参考页面,但我还没有到达任何地方。现在并没有真正开启所有气瓶。

感谢您提供任何(非常需要的)帮助!

1 个答案:

答案 0 :(得分:0)

您的问题是在data的几个地方main中阻止了header

也就是说,当您读入文件时,由于变量作用域,您将丢失指向数据的指针。也就是说,当你进行写操作时,它使用的指针指向随机存储器。

我认为你对header指针也有同样的问题[虽然我没有在下面解决这个问题,但修复方法类似]。另请注意,在两个读取块中,int main() { //Run read_WAV { header_type *header; char *filename[] = {//Various files}; // NOTE/BUG: this is scoped to _this_ block, so the write section below won't // see it // NOTE/BUG: this should be char *data and the function call should use &data char **data; read_pcm_wavefile(header, data, *filename); } //Run write_WAV { pcm_wavefile_header_type *header; char *filename[] = {//Various files}; // NOTE/BUG: this scoped 'data' declaration has none of the data in the read // sectioon above char *data; write_pcm_wavefile(header, data, *filename); } //Run read_WAV again on new files to ensure header info is valid { pcm_wavefile_header_type *header; char *filename[] = {//output files from write}; char *data; read_pcm_wavefile(header, data, *filename); } return(0); } 使用的类型不一致,即使它们执行相同的操作。

这是一个用bug注释的版本:

int main()
{
    char *data;

    //Run read_WAV
    {
        header_type *header;
        char *filename[] = {//Various files};
        read_pcm_wavefile(header, &data, *filename);
    }

    //Run write_WAV
    {
        pcm_wavefile_header_type *header;
        char *filename[] = {//Various files};
        write_pcm_wavefile(header, data, filename[0]);
    }

    free(data);

    //Run read_WAV again on new files to ensure header info is valid
    {
        pcm_wavefile_header_type *header;
        char *filename[] = {//output files from write};
        read_pcm_wavefile(header, &data, filename[0]);
    }

    return(0);
}

这是一个固定版本:

header

<强>更新

  

我已经解决了这个问题。仍然无法获得正确的输出,我在想是从每个函数传递数据/指针?

正如我所提到的,你需要对main做同样的事情,因为header需要指针被你的read函数填充。实际上,在读取调用之后,mainread_WAV的值未更改(即{em>未由int read_WAV(header_type *header, char **data, char *filename) 更新为你想要的。

变化:

int read_WAV(header_type **header, char **data, char *filename)

分为:

main

并在read_WAVmain

中进行所有相应的调整

此外,对header data应用header中针对read_WAV执行的相同作用域修正(即main为块作用域,但是,而不是功能作用域。)

因为即使原型更改为headerread_WAV也会失去write_WAV尝试传回的header值,int main(void) { char *data; header_type *header; char *infiles[FILECOUNT] = {//Various files}; char *outfiles[FILECOUNT] = {//Various files}; for (int fidx = 0; fidx < FILECOUNT; ++fidx) { //Run read_WAV read_pcm_wavefile(&header, &data, infiles[fidx]); //Run write_WAV write_pcm_wavefile(header, data, outfiles[fidx]); free(header); free(data); //Run read_WAV again on new files to ensure header info is valid read_pcm_wavefile(&header, &data, outfiles[fidx]); free(header); free(data); } return 0; } 会获得垃圾$('link[href^="../../../target/"][href$=".css"]'); 指针。

完成此工作后,请考虑块范围变量与函数范围变量的时间持续时间。换句话说,如果你设置一个变量,那么值何时“超出范围”[并变为无效]。

为了进行比较,这是使用块范围变量的版本:

dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
 }