这像时尚一样工作,做我认为你想要的:
#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);
这会抓住你那个特定块的数据。假设您使用的是小端系统,此时您应该能够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。然后,您需要适当地处理获得的数据以将其分解;即适当地拆分您读入的数据块。如果这是您希望阅读的唯一格式,您可以忽略其他块。
现在,问题仍然存在,什么是苹果格式,老实说我不知道!