これは、ファッションのようなストリームで機能し、私が望むことを実行します。
#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
が、本当にエレガントではない。
または、さらに良いことに、これを行うためのライブラリがどこかにあるはずです。
編集Waveファイルのヘッダーに応答して、固定されていてそれほど大きくないため、すべてをバッファーに読み込みます。
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ファイルは、多くの場合、2つのサブチャンク(データ形式を指定する「fmt」チャンクと実際のサンプルデータを含む「data」チャンク)で構成される単一の「WAVE」チャンクを持つ単なるRIFFファイルです。この形を「標準形」と呼びます。それが実際にどのように機能するかを誰が知っていますか。
ストリームに何もなくなるまで継続的なループで使用すると、RIFFのデータチャンクをいくつでも読み取ることができるようになるという指示を与えました。次に、取得したデータを適切に処理して分解する必要があります。つまり、読み込んだデータチャンクを適切に分割します。これが読み取ることを期待する唯一の形式である場合は、追加のチャンクを無視することができます。
さて、問題は残っています。アップルのフォーマットとは何ですか。正直なところ、私にはわかりません。