4

ディレクトリにたくさんのテキストファイルがあり、各テキストファイルには「info1.txt」、「info2.txt」などの名前が付けられています。すべてのテキストファイル名をハードコーディングせずに、ifstreamオブジェクトの配列内のすべてのテキストファイルを開くにはどうすればよいですか?次のコードが機能しないことは知っていますが、機能した場合に何をしたいのかという考えを伝えていると思います。

ifstream myFiles[5];
for(int i = 0; i < 5; i++){
    myFiles[i].open("info" + i + ".txt");
}

解決策はおそらく非常に単純だと思いますが、多くの調査、試行錯誤の末、私はまだそれを理解していません。ありがとう!

4

5 に答える 5

7

ファイル名の作成には、とを使用std::ostringstreamoperator<<ます。

次のようなコンテナクラスを使用する場合std::vector(たとえば、コンパイル時にの配列の大きさがわからないためifstream)、std::ifstreamはコピーできないため、は使用できませんがまたは;vector<ifstream>を使用できます。例えば:vector<shared_ptr<ifstream>>vector<unique_ptr<ifstream>>

vector<shared_ptr<ifstream>> myFiles;
for (int i = 0; i < count; i++)
{
    ostringstream filename;
    filename << "info" << i << ".txt";
    myFiles.push_back( make_shared<ifstream>( filename.str() ) );        
}

unique_ptr(およびC ++ 11の移動セマンティクス)を使用する場合:

vector<unique_ptr<ifstream>> myFiles;
for (int i = 0; i < count; i++)
{
    ostringstream filename;
    filename << "info" << i << ".txt";
    unique_ptr<ifstream> file( new ifstream(filename.str()) );
    myFiles.push_back( move(file) );
}

unqiue_ptrは移動可能shared_ptrなポインタであるため、参照カウントされないため、よりも効率的ですunique_ptr(したがって、よりもオーバーヘッドが少なくなります)。したがって、C ++ 11では、'がコンテナの外部で共有されていない場合に優先することができます。shared_ptrunique_ptrifstreamvector

于 2012-10-19T07:32:43.003 に答える
5

問題は、ファイル名を動的に作成することに関する部分だと思います。

簡単な解決策の1つは、std::ostringstreamそれを行うために使用することです。

ifstream myFiles[5];
for(int i = 0; i < 5; i++){
    ostringstream filename;
    filename << "info" << i ".txt";
    myFiles[i].open(filename.str());
}

ライブラリが古std::stringすぎて、呼び出しで引数を受け入れることができない場合openは、

    myFiles[i].open(filename.str().c_str());
于 2012-10-19T07:20:50.650 に答える
3

あなたのアイデアは小さな変更でうまくいくはずです:

myFiles[i].open((std::string("info") + itoa(i) + ".txt").c_str());
             // ^^^^^^^^^^^           ^^^^

また、はコピー可能なオブジェクトではないstd::vectorため、使用できないことに注意してください。ifstreamしたがって、アレイを引き続き使用します。

于 2012-10-19T07:19:43.050 に答える
1

私は通常std::stringstreamを使用します:

{
  std::stringstream filename;
  filename << "info" << i << ".txt" << std::ends;
  myFiles[i].open(filename.str().c_str());
}
于 2012-10-19T07:21:56.310 に答える
0

ifstreamオブジェクトの配列を持つことができますが、動的な長さが必要な場合、この方法でそれを行うことはできず、機能しませんstd::vector<ifstream>

したがって、ポインタが必要になります。std::vector<ifstream*>動作しますが、shared_ptrを使用する可能性があるためstd::vector<shared_ptr<ifstream> >動作します。利用可能な場合unique_ptrは、の代わりにそれを使用できますshared_ptr

次に、各要素をで作成する必要がありnewます。

また、文字列を適切に作成する必要があります。これを行うには、boost::formatまたはostringstreamまたは昔ながらの方法を使用できますsprintf

ちなみに、私はBoostのファイルシステムライブラリを検索してifstream、shared_ptrの煩わしさなしに、ベクター内でうまくいくことができる、より動的なものがあるかどうかを確認します。

于 2012-10-19T07:29:50.660 に答える