2011-02-07 9 views
2

テキストファイルにアクセスするとき、特定の行から読み込みたい。私のファイルが1000行で、行330を読みたいとしましょう。各行の文字数は異なります(行ごとに約100,000,000文字と言いましょう)。私は考えているfseek()ここで効果的に使用することはできません。".txt"ファイル内の情報にアクセスして確定行に移動

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

助けてもらえますか?

+0

「決定されました」と思っています。 :) – Maxpm

+1

オフトピックが、 "私は疑いがある"とは英語の間違いです。あなたは「私に質問がある」または「私が解決しようとしている問題がある」という意味です。 「疑う」とは主張に疑念を抱くことです。例えば、「彼は10kgの重さだと言いましたが、私はそれを疑っています。または "私はあなたがそれを持ち上げることができることを疑うことはありません。" – tenfour

+0

@tenfour:申し訳ありませんが、間違いではありません。それはあなたが慣れていたものとは異なる英語版の標準的な使用法です。 – btilly

答えて

1

ファイルをスキャンし、目的の行が見つかったので\ nオカレンスを数えてください。これが頻繁に行われ、ファイルを書き込む唯一の人であれば、そのような情報を含む索引ファイルを、「貧弱人索引」のようなデータを含むものと並べることができます多くの時間を節約することができます。

+0

問題は、行のすべての情報を読み込む必要がある場合、プロセスが長すぎることです。すべての行に10000000000文字があると考えてください。行330の最初の10文字を取得したい場合は、前の行をすべて読み込むのは意味がありません。何か案が?? – thomas

+1

あらかじめ作成されたインデックスがないと他の方法はないので、意味があります。改行は特別なものではありません。あなたは文字「k」の出現を数えることもできます。ファイルをスキャンする必要があります。 "行"は、ファイルシステムによって本質的に定義されていない、テキストファイル形式で定義された専門です。 – tenfour

2

ファイル全体をスキャンし、改行を検出してからカウントすることなく、行330が任意のテキストファイルから開始する場所を知る方法はありません。

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

+0

Yeap!あなたのファイルが書かれたときに、すべての行の終わりが "myfile << endl;"と書かれているとします。すべての行がどこから始まるかを知ることができます。 – thomas

+0

@thomas:あなたがファイルを書いているときに、改行がどこに行ったのか分かりました。しかし、その時点でその情報を保存しないと、読んでいるときに、今どこにいるのか分かりません。 – btilly

3

"MはファイルのN番目の行から始まります"というインデックスがない限り、ファイルから文字を読み込み、改行を数えて目的の行を見つけなければなりません。

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

+0

Yeap!私のファイルが書き込まれたとき、すべての行の終わりが "myfile << endl;"と書かれているとします。すべての行がどこから始まるかを知ることができます。だからアイデアは私の ".txt"ファイルにアクセスし、私が欲しいと思うほど多くの改行をループします。 – thomas

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; 
} 
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がどこにある最後の値はあなたを教えてくれます。

関連する問題