.JPG、.BMP (たとえば) などのさまざまな一般的なファイルから大量のデータを挿入したいリソース ファイルを作成しており、それをバイナリにしたいと考えています。インデックス別に整理されたこれらのデータを後で取得するために何かをコーディングするつもりです。
float randomValue = 23.14f;
ofstream fileWriter;
fileWriter.open("myFile.dat", ios::binary);
fileWriter.write((char*)&randomValue, sizeof(randomValue));
fileWriter.close();
//With this my .dat file, when opened in notepad has "B!¹A" in it
float retrieveValue = 0.0f;
ifstream fileReader;
fileReader.open("myFile.dat", ios::binary);
fileReader.read((char*)&retrieveValue, sizeof(retrieveValue));
fileReader.close();
cout << retrieveValue << endl; //This gives me exactly the 23.14 I wanted, perfect!
これはうまく機能しますが、そこで何が起こっているのかを正確に理解したいと思います。randomValueのアドレスを char* に変換して、このアドレスの値をファイルに書き込みますか?
配列に対してこれを行う必要があり、これを行うことができないため、私も興味があります:
int* myArray = new int[10];
//fill myArray values with random stuff
fileWriter.open("myFile.dat", ios::binary);
fileWriter.write((char*)&myArray, sizeof(myArray));
fileWriter.close();
私が理解していることから、これはすべての配列ではなく、最初のアドレスの値をファイルに書き込むだけです。したがって、テストのために、変数をファイルに書き込む char* に単純に変換し、変数に戻して値を正しく取得しているかどうかを確認しようとしているので、次のようにします。
int* intArray = new int[10];
for(int i = 0; i < 10; i++)
{
cout << &intArray[i]; //the address of each number in my array
cout << intArray[i]; //it's value
cout << reinterpret_cast<char*>(&intArray[i]); //the char* value of each one
}
しかし、何らかの理由で、このコードを実行するとコンピューターが「ビープ音」を鳴らします。配列中に、これらを char* に保存し、int に変換しようとしていますが、期待した結果が得られず、非常に長い値が得られます。何かのようなもの:
float randomValue = 23.14f;
char* charValue = reinterpret_cast<char*>(&randomValue);
//charValue contains "B!¹A" plus a bunch of other (un-initiallized values?) characters, so I'm guessing the value is correct
//Now I'm here
charValue を randomValue に変換したいのですが、どうすればよいですか?
編集:以下の回答には貴重な情報がありますが、私の(元の)問題は解決しません。これらのタイプの変換をテストしていたのは、BMP、JPG、MP3 などのリソース ファイルの束を選択し、それらをいくつかの基準で整理された単一の .DAT ファイルに保存するコードを実行しているためです。わかった。
後で、このリソース ファイルを使用して、これらのコンテンツを読み込んで、コーディング中のプログラム (ゲーム) にロードします。
私がまだ考えている基準ですが、次のようなことが可能かどうか疑問に思っていました:
//In my ResourceFile.DAT
[4 bytes = objectID][3 bytes = objectType (WAV, MP3, JPG, BMP, etc)][4 bytes = objectLength][objectLength bytes = actual objectData]
//repeating this until end of file
次に、リソース ファイルを読み取るコードで、次のようなことを行います (未テスト)。
ifstream fileReader;
fileReader.open("myFile.DAT", ios::binary);
//file check stuff
while(!fileReader.eof())
{
//Here I'll load
int objectID = 0;
fileReader((char*)&objectID, 4); //read 4 bytes to fill objectID
char objectType[3];
fileReader(&objectType, 3); //read the type so I know which parser use
int objectLength = 0;
fileReader((char*)&objectLength, 4); //get the length of the object data
char* objectData = new char[objectLength];
fileReader(objectData, objectLength); //fill objectData with the data
//Here I'll use a parser to fill classes depending on the type etc, and move on to the next obj
}
現在、私のコードは元のファイル (BMP、WAV など) を処理してクラスに入力しています。これらのファイルのデータをバイナリ データ ファイルに保存する方法を知りたいです。たとえば、BMP データを管理するクラスには次のようなものがあります。
class FileBMP
{
public:
int imageWidth;
int imageHeight;
int* imageData;
}
ロードするときは、次のように呼び出します。
void FileBMP::Load(int iwidth, int iheight)
{
int imageTotalSize = iwidth * iheight * 4;
imageData = new int[imageTotalSize]; //This will give me 4 times the amount of pixels in the image
int cPixel = 0;
while(cPixel < imageTotalSize)
{
imageData[cPixel] = 0; //R value
imageData[cPixel + 1] = 0; //G value
imageData[cPixel + 2] = 0; //B value
imageData[cPixel + 3] = 0; //A value
cPixel += 4;
}
}
したがって、ピクセルあたり [RGBA] の形式の値を含むこの 1 次元配列があり、後で画面に描画するために使用します。この配列だけを、上で述べたように計画しているバイナリ データ形式で保存し、それを読み取ってこの配列に入力できるようにしたいと考えています。
このようなコードは要求が多すぎると思うので、これらの値をバイナリ ファイルに保存し、それを読み戻して埋めるために知っておくべきことを理解したいと思います。
長文すみません!
edit2:最初の編集を行うことで問題を解決しました...貴重な情報をありがとう、私も自分が何をしたいのかを知ることができました!