2013-05-06 39 views
6

ファイルを一度読み込んでその中に含まれる行の数を確認し、再度読み込んで各行のデータを配列に格納することができます。ファイルを閉じて再び開くよりも2回読む方が良い方法はありますか?ここに私が持っているものがありますが、それは非効率的だと恐れています。同じファイルを2回連続して読み込む方法

int numOfMappings = 0; 
ifstream settingsFile("settings.txt"); 
string setting; 
while(getline(settingsFile, setting)) 
{ 
    numOfMappings++; 
} 
char* mapping = new char[numOfMappings]; 
settingsFile.close(); 
cout << "numOfMappings: " << numOfMappings << endl; 
settingsFile.open("settings.txt"); 
while(getline(settingsFile, setting)) 
{ 
    cout << "line: " << setting << endl; 
} 
+2

あなたはC++を使っているので、配列の代わりに 'vector'を使うことができます:http://www.cplusplus.com/reference/vector/ – Patashu

+0

情報を格納するのに'ベクトル '最初にファイルから読み込むと、ベクタはメモリが必要になると自動的にサイズが変更されます。 –

+0

[こちら](http://en.cppreference.com/w/cpp/io/basic_ostream/seekp)をご覧ください。たぶん[ここ](http://en.cppreference.com/w/cpp/io/basic_istream/seekg)。 – ChiefTwoPencils

答えて

16
settingsFile.clear(); 
settingsFile.seekg(0, settingsFile.beg); 
0

だけ使用します。

settingsFile.seekg(0, settingsFile.beg); 

これは非常に先頭にファイルポインタを巻き戻しますので、あなたは閉じて再オープンすることなく、再びそれを読むことができます。

+3

誰かが配列を見たときに、現在のデフォルトの答えではなく、質問に答えてくれるのがうれしいです。 "...ベクトル..."。 +1 – ChiefTwoPencils

+0

これは動作しません。 'while(getline(settingsFile、setting))'は決して起こらない。 – Celeritas

+2

@Celeritasこれは、eofbitがまだ設定されているためです。ループの前にfile.clear()を呼び出します。 – jrok

3

これは非効率的です。std::vectorを使用し、ファイルを一度だけ読んでください。

vector<string> settings; 
ifstream settingsFile("settings.txt"); 
string setting; 
while (getline(settingsFile, setting)) 
{ 
    settings.push_back(setting); 
} 
+1

ファイルが大きすぎてベクターがメモリに収まらない場合は、この方法を使用することは適切ではないかもしれません。 – mvp

+3

@mvp:それは配列に対しても当てはまります。 –

3

(あなたはすべての内部エラーフラグをリセットするには、カーソルの位置とifstream::clear()を変更するifstream::seekg()を使用することができます(たとえば、再びそれを読むために)戻ってその先頭にファイルを巻き戻すには、それ以外の場合は、あなたがまだである表示されますファイルの終わり)。

第2に、ファイルを一度しか読み取れず、ファイルを解析している間に、覚えが必要な内容を一時的なstd::dequeまたはstd::listに保存することを検討することをお勧めします。後で特定のコンテナが必要な場合は、一時コンテナから配列(またはstd::vector)を作成できます。

関連する問題