
STLで、vectorのファイルへの読み込み。
先ほどの質問 (http://oshiete.goo.ne.jp/qa/6271982.html) は
out.write((char *) &testvector, sizeof(int) * testvector.size());
とすることで解決できたかなと思うのですが (コンパイルが通っただけですが) 、一方で読み込みとなると、read を使うとバイト数の指定が必要となります。しかし可変長配列なので、長さは不定であると考えると、どのように読み込んだらよろしいのでしょうか。書き出す時に vector の長さを書き出しておくとかそういう方法になるのでしょうか。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
read()に1を指定すれば、ファイルから1byteだけ読み出せます。
ファイルの終端までループでまわせば、ファイル全体を読み込んだことになりますが、必要なバッファは1バイトで済みます。>> 書き出す時に vector の長さを書き出しておくとかそういう方法になるのでしょうか。
この方法もありです。
readを呼び出す前にデータ長がわかれば、その分、事前にmalloc()あるいはnewすることで対応します。これなら、ループが必要なくて、プログラムも簡単になりますね。
ただし、エラーチェックは入れてね。
悪意のある人間が、例えば1テラバイトを要求するデータを捏造して、プログラムに与えたときにも対応できるように、上限チェックを入れるとか。

No.1
- 回答日時:
VC++ 2010でテストしています。
出力されたバイナリファイルが、「vector<int>のシリアライズされたものである」、ということが常に保証されているのであれば、まずシークによりファイルサイズを取得して、先頭位置に戻し、再度読み込むようにします。
なお、通例としてバイナリファイルは、ファイルの先頭にファイルヘッダ(たとえばヘッダ情報構造体をシリアライズしたもの)を書き込んでおき、どういうフォーマットで記述されているかを記録しておくのがベターです。
#include <fstream>
#include <cstdio>
#include <vector>
#include <conio.h>
using namespace std;
bool SaveToFile(const char* fileName)
{
vector<int> testVec;
for (int i = 0; i < 10; i++)
{
testVec.push_back(i);
}
ofstream ofs(fileName, ios::binary);
if (ofs.fail())
{
puts("Failed to save the binary file!");
return false;
}
ofs.write(reinterpret_cast<const char*>(&testVec[0]), sizeof(int) * testVec.size());
ofs.flush();
if (ofs.fail())
{
puts("Failed to save the binary file!");
return false;
}
else
{
puts("Succeeded to save the binary file.");
return true;
}
// ofstream はデストラクタで close() を自動的に呼び出してくれます。
}
bool LoadFromFile(const char* fileName)
{
ifstream ifs(fileName, ios::binary);
if (ifs.fail())
{
puts("Failed to open the binary file!");
return false;
}
else
{
puts("Succeeded to open the binary file.");
}
const size_t fileSize = static_cast<size_t>(ifs.seekg(0, ios::end).tellg());
ifs.seekg(0, ios::beg); // 先頭に戻す。
if (fileSize > 0 && fileSize % sizeof(int) == 0)
{
// ファイルサイズがゼロでなく、かつ sizeof(int) の倍数である場合。
vector<int> testVec(fileSize / sizeof(int));
ifs.read(reinterpret_cast<char*>(&testVec[0]), fileSize);
for (size_t i = 0; i < testVec.size(); i++)
{
printf("Vec[%03u] = %d\n", static_cast<unsigned>(i), testVec[i]);
}
}
else
{
// ファイルサイズがゼロであるか、または sizeof(int) の倍数でない場合。
puts("The binary file is invalid format!");
return false;
}
// ifstream はデストラクタで close() を自動的に呼び出してくれます。
return true;
}
int main()
{
const char* fileName = "serialized_vector_int.bin";
if (::SaveToFile(fileName))
{
::LoadFromFile(fileName);
}
puts("Press any key to exit...");
_getch();
return 0;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 2 2023/07/21 10:51
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- C言語・C++・C# 100バイトのバイナリファイルを読み込んで別のファイルに書き込みたいのですが、型をどうすればいいのか 1 2022/11/03 17:11
- システム 外付けHDDの初期化について 4 2023/03/05 21:19
- システム 外付けHDDの初期化について 4 2023/03/05 20:00
- C言語・C++・C# このプログラミング誰か教えてくれませんか 3 2022/05/13 17:27
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
Win32APIで作るコンボボックス...
-
#define _CRT_SECURE_NO_WARNIN...
-
ラップ関数とはどんなものですか?
-
「指定されたキャストは有効で...
-
未解決の外部シンボル _printf...
-
異なる文字列のマッチングを、D...
-
(int *)の意味
-
ColorをRGBで指定する方法
-
if と配列の組み合わせ
-
C言語での奇数の和
-
C言語 エラーの原因がわからな...
-
線形リストについてのプログラ...
-
数字列を3桁ごとにカンマで区切...
-
C言語で三目並べをするプログラ...
-
system関数がうまくいかない
-
C++でvectorにテキストファイル...
-
式は定数値が必要です」という...
-
read関数をノンブロッキングで...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
複数桁10進数の*桁目だけを抽出...
-
ラップ関数とはどんなものですか?
-
C言語 エラーの原因がわからな...
-
(int *)の意味
-
【C++】関数ポインタの使い方
-
if と配列の組み合わせ
-
構造体の勉強中です 合計点の高...
-
windows-findstrの正規表現を使...
-
C言語で分からないところがあり...
-
int型の変数値をバイト列として...
-
PowerShellがうまくいかない
-
C言語での奇数の和
-
「{ } で囲むだけ」は正しい?
-
std::set<int> で、ある値が何...
-
実数の整数部,小数部の取得
-
エラー 添字が付けられた値が、...
-
int16_t の _t は何?
おすすめ情報