2

テキストファイルにアクセスする際、特定の行から読み込みたい。ファイルに 1000 行があり、330 行を読みたいとします。各行の文字数は異なり、非常に長くなる可能性があります (1 行あたり約 100,000,000 文字としましょう)。fseek()ここは有効に使えないと思います。

改行を追跡するためのループについて考えていましたが、それを実装する方法が正確にはわかりません。また、それが最善の解決策になるかどうかもわかりません。

何かお手伝いできますか?

4

5 に答える 5

3

ファイル内に「行Mは位置Nから始まる」というインデックスがない限り、ファイルから文字を読み取り、目的の行が見つかるまで改行を数える必要があります。

std::getline各行の内容を保存するstd::istream::ignore場合、または目的の行が見つかるまで読み取った行の内容を破棄する場合は、を使用して行を簡単に読み取ることができます。

于 2011-02-07T15:53:10.047 に答える
2

ファイル全体をスキャンし、改行を見つけてカウントしない限り、任意のテキストファイルのどこから行330が始まるかを知る方法はありません。

これを1回だけ行う必要がある場合は、スキャンします。何度も実行する必要がある場合は、1回スキャンして、すべての行が始まるデータ構造リストを作成できます。これで、その行だけを読み込もうとする場所を見つけることができます。データを整理する方法をまだ考えている場合は、ランダムアクセスに他のタイプのデータ構造を使用することをお勧めします。あなたが解決しようとしている実際の問題を知らずに、どれを推薦することはできません。

于 2011-02-07T15:52:55.677 に答える
1

目的の行が見つかったので、ファイルをスキャンして\n発生回数を数える必要があると思います。これが頻繁な操作であり、ファイルを作成するのがあなただけである場合は、そのような情報を含むインデックスファイルを、データを含むインデックスファイルと並べて管理することができます。これは一種の「poor-man-index」ですが、多くの時間を節約できます。

于 2011-02-07T15:52:05.163 に答える
1

ファイルにインデックスを作成します。これは「怠惰に」行うことができますが、バッファーがいっぱいになると、各文字をスキャンすることもできます。

2 バイトの '\n' を使用する Windows 上のテキスト ファイルの場合、改行が発生する位置まで読み取った文字数はオフセットになりません。したがって、getline() を呼び出すたびに「シーク」を行う必要があります。

何かのようなもの:

std::vector< off_t > lineNumbers;
std::string line;
lineNumbers.push_back(0); // first line begins at 0
while( std::getline( ifs, line ) )
{
   lineNumbers.push_back(ifs.tellg());
}

最後の値は、EOF がどこにあるかを示します。

于 2011-02-07T15:59:00.740 に答える
0

ループでfgetsを実行してみてください

/* fgets example */
#include <stdio.h>

int main()
{
   FILE * pFile;
   char mystring [100];

   pFile = fopen ("myfile.txt" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     fgets (mystring , 100 , pFile);
     puts (mystring);
     fclose (pFile);
   }
   return 0;
}
于 2011-02-07T15:58:29.743 に答える