写入二进制文件时的开销数据

The*_*eer 19 c

我想写一个包含16位整数的数组作为文件的原始二进制文件,并尝试使用以下示例:

#  define __int8_t_defined
__intN_t (8, __QI__);
__intN_t (16, __HI__);
__intN_t (32, __SI__);
__intN_t (64, __DI__);

int main(int argc, char *argv[])
{
    FILE * rawf;
    rawf = fopen("./rawPcm","wb");
    int16_t buff[] = {0,0,0};
    fwrite(buff,sizeof(int16_t), sizeof(buff),rawf);
    fwrite(buff,sizeof(int16_t), sizeof(buff),rawf);  
    fclose(rawf);
}
Run Code Online (Sandbox Code Playgroud)

但是,输出包含的不仅仅是零.

$ hexdump -v rawPcm 
0000000 0000 0000 0000 85fd 0804 0001 0000 0000
0000010 0000 85fd 0804 0001                    
0000018
Run Code Online (Sandbox Code Playgroud)

它写0000 0000 0000 85fd 0804 0001的每一次fwrite(buff,sizeof(int16_t), sizeof(buff),rawf);我期望只得到0000 0000 0000.

附加数据代表什么85fd 0804 0001,如何防止它发生?

Moh*_*ain 19

附加数据代表什么 85fd 0804 0001

可能是一些随机垃圾数据.

我该如何防止它发生?

fwrite(buff,sizeof(int16_t), sizeof(buff),rawf); 应该写成:

fwrite(buff,sizeof(int16_t), sizeof(buff) / sizeof(buff[0]),rawf);
/*               ^                          ^^^^^^^^^^^^^^^      */
/*       size of each object      Count of objects               */
/*              (2)                  (3)                         */

/* or */
fwrite(buff, sizeof buf[0], sizeof buff / sizeof buff[0], rawf);
Run Code Online (Sandbox Code Playgroud)

sizeof buff / sizeof buff[0]获取对象(或成员)数量数组长度,同时sizeof buff给出数组的大小(以字节为单位).

所以你正在阅读buff并将其写入文件并调用未定义的行为.在您的情况下,您看到随机垃圾数据被写入输出文件.

在您的情况下,sizeof每个元素buff是2个字节,buff数组有3个成员,导致总大小为6个字节.在你写的时候fwrite(buff,sizeof(int16_t), sizeof(buff),rawf);,每个2字节的6个对象被写入文件,这不是你想要做的事情.

现在您正在编写6个int16_tbuff[0]ie 开始buff[0..5]到输出的类型(大小)数据.buff[0..2]0预期的,buff[3..5]是垃圾.


Bat*_*eba 9

的第三个参数fwrite由第二参数指定大小的元件.它不是您当前正在执行的总大小(以字节为单位).

所以你超越你的缓冲区.