以下功能不起作用,即退出:
fread(buf, 1, 4, stdin);
buf[4] = '\0';
if (strcmp((char*)buf, "data")) exit(EXIT_FAILURE);我认为,如果我能够手动推动fread更远的流,它将最终击中“数据”。
换句话说,我如何增加fread,使其跳过字节。
代码的例子总是值得赞赏的。
谢谢!
编辑1
基本上,我是在解析iPhone上的wav文件的头。这给我带来了一些麻烦,我相信这与苹果格式化音频文件的方式有关。有人向我推荐我在溪流中跑步,直到我得到“数据”,然后再往前走。
我希望这能澄清一些事情。
编辑2
下面是关于wav文件头应该是什么样子的文档,但我想知道苹果的格式化方式是否会造成这种情况的不准确。
您会注意到,“数据”被36抵消,这是4的倍数。
发布于 2011-02-16 13:06:02
它像时尚一样在流中工作,做我认为你想做的事情:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv)
{
long pos = 0;
char buf;
char str[5] = {'\0','\0','\0','\0','\0'};
while ( fread(&buf, sizeof(char), 1, stdin) > 0 )
{
pos++;
str[0] = str[1];
str[1] = str[2];
str[2] = str[3];
str[3] = buf;
str[4] = '\0';
/* uncomment to see what got read ** printf("Read %s\n", str); */
if ( strcmp(str, "data") == 0 )
{
break;
}
}
printf("\"data\" occured after %ld bytes\n", pos);
return 0;
}这是通过使用一个名为str的缓冲区并旋转其中的位置来实现的。它将在data出现之前工作。
注意,它读取二进制数据,而不是文本。因此,stdin上的任何内容都会被阅读,包括新行。但是,如果您将其调整为文件句柄,那就没有问题了。
你也许可以把这个包括进去。使用fread的问题在于,通过设计:
流的文件位置指示符(如果定义的话)应由成功读取的字节数来推进。
因此,如果一次前进4个字节,除非数据从数据开始时正好是4的倍数,否则就会错过它。例如:
123DATA如果一次读取4个字节,则失败。
现在,考虑到这是一个有文档记录的文件格式,是否有一些头规范可以告诉您标题上的字段有多宽?或者至少在它们变化的地方,这样你才能正确地把它们读掉?阅读直到data工作,但并不优雅,真的。
或者,更好的是,我相信一定有一个图书馆来做这件事。
编辑作为对波形文件头的响应,因为它是固定的而不是那么大,所以将整个文件读取到一个缓冲区中。
uint8_t* hdr = malloc(36*sizeof(uint8_t));
fread(hdr, sizeof(uint8_t), 36);别忘了自由。此时,您将提取整个标头。我使用uint8_t绝对是8位。在这个阶段,您可以使用一些有趣的技巧,比如将数据转换为结构。只是要注意田里的恩典。
从那时起,我相信这条小溪对你来说是一条条的。你需要做的第一件事是:
uint8_t chkid;
uint8_t chksz;
fread(&chkid, sizeof(uint8_t), 4, stream);
fread(&chksz, sizeof(uint8_t), 4, stream);会给你那块东西的数据。假设您使用的是一个小的endian系统,此时您应该能够直接将chksz作为一个整数使用,所以现在您可以这样做:
uint8_t dataframe = malloc(chksz * sizeof(uint8_t));您可以在其中读取数据:
fread(&dataframe, sizeof(uint8_t), chksz, stream);当然,这是假设Apple格式就是描述的格式。现在,从这一页:
WAVE文件格式是Microsoft用于存储多媒体文件的RIFF规范的一个子集。一个RIFF文件从一个文件头开始,然后是一系列数据块。WAVE文件通常只是一个带有单个"WAVE“块的RIFF文件,其中包含两个子块--一个指定数据格式的"fmt”块和一个包含实际示例数据的“数据”块。将这种形式称为“规范形式”。谁知道这一切到底是怎么回事。
我已经给了您指示,如果在一个连续的循环中使用,直到流上没有更多的数据,将允许您读取任意数量的数据块a-la RIFF。然后,您需要适当地处理所获得的数据,以便对其进行分解;也就是说,将您适当读取的数据块拆分。如果这是您希望阅读的唯一格式,则可以忽略其他块。
现在,问题仍然存在,苹果的格式是什么,老实说,我不知道!
发布于 2011-02-16 13:14:18
我不认为ASCII中data的第一次出现是数据头的开始,因为这四个字节也可能作为WAV格式格式块的一部分出现。
/* Returns the size of the data payload */
off_t skip_to_data_payload(FILE *fp)
{
unsigned char buf[4];
int i;
off_t size;
// the "data" magic should start at byte 36
for (i=0; i<9; i++)
fread(buf, 1, 4, fp);
fread(buf, 1, 4, fp);
if (memcmp(buf, "data", 4) != 0)
return (off_t)(-1);
// read size, assume little-endian
fread(buf, 1, 4, fp);
off_t size = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[4] << 24);
return size;
}注意:我假设PCM编码和小endian文件。由于苹果在过去使用过大的endian处理器,你真的应该检查一下。(或者使用库。)
发布于 2011-02-16 12:38:40
该strcmp将永远无法工作,因为您需要一个额外的字符来终止字符串(\0),并且您已经用完了您的字符串的所有4个字符。试一试strncmp。如果在使用stdin时添加了更多的字符,请不要忘记行提要。
https://stackoverflow.com/questions/5016395
复制相似问题