ifstream
(または実際には入力ストリーム)をイテレータのように動作する形式にするには、istream_iterator
またはistreambuf_iterator
テンプレートクラスを使用します。前者は、書式設定が問題となるファイルに便利です。入力の書式設定を無視し、
#include <fstream>
#include <vector>
#include <iterator> // needed for istream_iterator
using namespace std;
int main(int argc, char** argv)
{
ifstream infile("my-file.txt");
// It isn't customary to declare these as standalone variables,
// but see below for why it's necessary when working with
// initializing containers.
istream_iterator<int> infile_begin(infile);
istream_iterator<int> infile_end;
vector<int> my_ints(infile_begin, infile_end);
// You can also do stuff with the istream_iterator objects directly:
// Careful! If you run this program as is, this won't work because we
// used up the input stream already with the vector.
int total = 0;
while (infile_begin != infile_end) {
total += *infile_begin;
++infile_begin;
}
return 0;
}
istreambuf_iterator
が通過読み取るために使用された時点で単一の文字をファイル:たとえば、次のように空白で区切られた整数の完全なファイルは、ベクトルのイテレータ範囲のコンストラクタに読み込むことができます。つまり、空白、改行文字などのすべての文字が返されます。アプリケーションによっては、それが適切かもしれません。
注:Scott Meyersはで有効なSTLを説明していますが、なぜ上記の別の変数宣言がistream_iterator
である必要がありますか。
ifstream infile("my-file.txt");
vector<int> my_ints(istream_iterator<int>(infile), istream_iterator<int>());
しかし、C++は実際に非常に奇妙な方法で、二行目を解析します。通常は、このような何かをするだろう。それはmy_ints
という名前の関数の宣言とみなされ、2つのパラメータをとり、vector<int>
を返します。最初のパラメータはタイプistream_iterator<int>
であり、名前はinfile
です(paranthesesは無視されます)。 2番目のパラメータは、名前がなく、引数がゼロの関数ポインタ(paranthesesのため)であり、タイプistream_iterator<int>
のオブジェクトを返します。
あなたはそれを見ていない場合、かなりクールだけどかなり悪化します。私個人的にではなく、今
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main(int argc, char** argv)
{
ifstream input("my-file.txt");
istreambuf_iterator<char> input_begin(input);
istreambuf_iterator<char> input_end;
// Fill a char vector with input file's contents:
vector<char> char_input(input_begin, input_end);
input.close();
// Convert it to an array of unsigned long with a cast:
unsigned long* converted = reinterpret_cast<unsigned long*>(&char_input[0]);
size_t num_long_elements = char_input.size() * sizeof(char)/sizeof(unsigned long);
// Put that information into a vector:
vector<unsigned long> long_input(converted, converted + num_long_elements);
return 0;
}
:ここでEDIT
は、エンドツーエンドのレイアウトの64ビット数のファイルを読み込むことistreambuf_iterator
を使用した例です(reinterpret_cast
を使って、char_input
の配列を公開しています)、私はistreambuf_iterator
とよく似ていないので、64ビット文字よりもテンプレート化されたものを快適に使うことができません。はるかに簡単です。
ファイル内の整数は、改行文字、スペースなどで区切られていますか?もしそうなら、 'istream_iterator'はあなたの友人です。 – Dawson
@Toolboxは返事と解決策に感謝します!ファイルの形式は、セパレータなしの64ビットのリトルエンディアン符号なし整数です。だからistreambuf_iteratorのように見える方法ですか? istreambuf_iteratorをベクトルに変えるのを助けることができますか? –
Donny
何かを振り払って(そしてそれがコンパイルされていることを確認して)私にしばらくお待ちください。 – Dawson