0

私は C が初めてで、EOF までファイルをスキャンし、特定のキーワードを含む行を選択し、最後の行が検索された後にオフセットを設定する C プログラムを構築しようとしています。スキャンが再度実行されると、ファイルがスキャンされます。今回は、保存されたオフセットから始まり、EOF まで下方向に続きます。

ファイル I/O のさまざまな機能に頭を悩ませようとしていますが、fopen()、fseek()、fgets()、ftell() などを呼び出す手順をつなぎ合わせて、やりたいことを実行するのに苦労しています。することです。誰かが私を正しい方向に向けたり、これを行うために必要なことを説明したりできますか?

ありがとうございました!

4

3 に答える 3

1

getlineあなたの場合、読み取り、およびオフセットの取得/設定(および個々の行の検索)に使用するftellことfseekstrstrお勧めします。

オフセットの保存が何であるかはわかりませんが、次のようになります。

int pick_lines(const char *filename, const char *keyword, long *offset)
{
    FILE *fp;
    char *line = NULL;
    size_t len = 0;

    if (offset == NULL || (fp = fopen(filename, "r")) == NULL)
        return 1;

    if (*offset > 0 && fseek(fp, *offset, SEEK_SET) != 0) {
        fclose(fp);
        return 1;
    }

    while (getline(&line, &len, fp) != -1) {
        if (strstr(line, keyword) != NULL)
            printf("%s", line); // or do something else with chosen line
    }

    if ((*offset = ftell(fp)) < 0) {
        free(line);
        fclose(fp);
        return 1;
    }

    free(line);
    fclose(fp);
    return 0;
}

ここoffsetに入出力パラメーターがあります。逆参照された値は、指定されたオフセット ( で始まる*offset == 0) をシークするために使用され、その後、新しいオフセットにリセットされます。

この関数は、 を含むすべての行を出力するだけkeywordです。代わりに行の配列を返したい場合は、少し余分な作業が必要です。

使用例は次のとおりです。

long offset = 0;
pick_lines(filename, keyword, &offset);
// append lines to file
pick_lines(filename, keyword, &offset);
// ...
于 2015-07-17T12:10:21.830 に答える
0

あなたがやりたいことは、最後の結果が見つかった場所を定義する「ヘッダー」でファイルを開始することです。このようにして、その情報はファイル自体に書き込まれ、保存されます。最大 4GB のサイズのファイルでオフセットを表すには、8 桁の 16 進数値で十分です。何かのようなもの:

00000022<cr><lf>
Text...<cr><lf>
More text...<cr><lf>
~ <cr><lf>  <-- this '~' is whatever we're looking for
Other stuff...<cr><lf>

ここでいくつかの仮定を立てています。まず、これは Windows の場合で、テキスト行は<cr><lf>文字 (それぞれ 0x0D と 0x0A) で終了します。Unix の場合は、それ<lf>のみになります。Mac の場合は、それ以外<cr>の場合もあります。この例ではそれらを数えました。これは、ANSI スタイルの文字列を想定しています。つまり、8 ビット エンコーディング (1 文字 = 1 バイトのデータ) を意味します。Unicode やその他の文字列形式でも同じ機能を実現できます。キャラクター。(Unicode では、1 文字あたり 2 バイトです。したがって、Unicode と ANSI 文字列操作を混在させると問題が発生することが予想されます。)

ここで、「ヘッダー」の値は 0x22 または 34 の 10 進数であり、ファイルの先頭からすべての文字を数えると、34 番目のカウントで「~」に達します。したがって、「ヘッダー」は、最後の検索結果が見つかった場所を指します。

これがどのように機能するかは次のとおりです。最初、このヘッダー値はゼロだったので、コードはこれを読み取り、まだ検索されていないことを認識します。「~」文字が見つかるまで、コードがファイル全体をスキャンし、文字ごとに 1 ずつインクリメントするとします。次に、先頭に戻り、このカウント値を 8 文字のテキスト文字 (itoaまたはsprintf) に変換し、ファイルのこの部分をそれで上書きします。さらに検索するために、すべてをもう一度見つけたり、完了したり、処理したりします。次にこのファイルが処理されるとき、コードはこのヘッダー値を読み取り、テキストからuint( ) に変換し、このオフセットに 1 を加えatoiた位置までファイルをシークし(これを再びキャッチしたくないため)、開始します。再度スキャンします。

ここにある他のものには、実験を開始するための実際のコードの良い例がいくつかあります。単語や一連の数字など、単なる文字以上のものを探している場合は、スキャン部分が遅くなり、より複雑になることに注意してください。単純な文字や単語の代わりに「トークン」を複雑にスキャンすることは、辞書編集分析と呼ばれ、それはまったく別のトピックです。GoogleFlex and BisonまたはYACCなど

于 2015-07-17T12:33:28.697 に答える