1

次のようなtxtファイルがあります。

"shoes":12
"pants":33
"jacket":26
"glasses":16
"t-shirt":182

ジャケットの数を編集する必要があります(たとえば、26 から 42 に)。だから、私はこのコードを書きましたが、「ジャケット」という単語がある特定の行を編集する方法がわかりません:

#include <stdio.h>

int main() {
    char row[256];
    FILE *fp;

    if (!(fp=fopen("myfile.txt","rw"))) {
        printf("Error");
        return 1;
    }

    while (!feof(fp)){
        fgets(row, 256, fp);
        // if there is the "jacket" in this row, then edit the row
    }

    fclose (fp);
    return 0;
}
4

5 に答える 5

5

残念ながら、これに対する簡単な解決策はありません。

一般的な方法は、すべての行 (変更されているかどうかに関係なく) を一時ファイルに書き込み、その一時ファイルを既存のファイルの上に移動することです。

于 2012-04-19T09:29:16.113 に答える
4

古い値と新しい値の文字数が同じ場合 (あなたのケース)、それらを上書きすることができます:

FILE* fp = fopen("x.txt", "r+"); // note: r+, not rw
char row[256];
char* string = "\"jacket\":"; // note: contains punctuation
char* newvalue = "42\n"; // note: contains a line break

while (!feof(fp)) // note: feof is bad style
{
    long pos = ftell(fp);
    fgets(row, 256, fp); // note: might add error handling

    // check if there is the "jacket": in this row,
    if (strncmp(row, string, strlen(string)) == 0)
    {
        // check that the old length is exactly the same as the new length
        // note: assumes the row contains a line-break \n
        if (strlen(row) == strlen(string) + strlen(newvalue))
        {
            // then edit the row
            fseek(fp, (long)(pos + strlen(string)), SEEK_SET);
            fputs(newvalue, fp);
            fseek(fp, (long)(pos + strlen(string) + strlen(newvalue)), SEEK_SET);
        }
        else
        {
            printf("Too bad, cannot change value");
        }
    }
}
fclose(fp);

ファイル形式を変更してパディングを含めることができます。次に例を示します。

"shoes":12____
"pants":33____
"jacket":26____
"glasses":16____
"t-shirt":182___

ここで_はスペース文字を視覚化します。このファイル形式は、最大 999999 個のアイテムをサポートします。このような変更を行う場合は、上記のコードを変更して、スペースの数などを確認および調整する必要があります。

于 2012-04-19T10:48:43.930 に答える
0

おそらく gawk を使用する方が簡単です。

gawk -f edit_row.awk <myfile.txt >tmp.txt && mv tmp.txt myfile.txt

edit_row.awk

BEGIN {
    FS = ":"
}

{
    if ($1 == "\"jacket\"") {
        print $1 ":" 42
    } else {
        print
    }
}

本当に c で実行したい場合は、tmpfile() 関数を使用できます。

#include <stdio.h>
#include <string.h>

int main() {
    char row[256];
    char *file_name = "myfile.txt";
    FILE *file_pointer;
    FILE *temp_file;

    char col_a[101] = "";
    unsigned int col_b = 0;
    char filter[] = "\"jacket\"";
    size_t filter_length = sizeof(filter) - 1;

    file_pointer=fopen(file_name,"r+");
    temp_file=tmpfile();

    while (fgets(row, 256, file_pointer) != NULL) {
        if (strncmp(row, filter, filter_length) == 0) {
            fprintf(temp_file,"%s:46\n", filter);
        } else {
            fprintf(temp_file, "%s", row);
        }
    }


    rewind(temp_file);
    rewind(file_pointer);

    while (fgets(row, 256, temp_file) != NULL) {
        fputs(row, file_pointer);
    };

    fclose(file_pointer);
    fclose(temp_file);
    return 0;
}
于 2012-04-19T11:41:32.237 に答える
0

テキスト ファイルは、単一の行または列を 1 回で変更できるデータベースとは異なります。c/c++ では、コーディングが重複するという犠牲を払って非常に困難になります。

于 2012-04-19T09:40:53.853 に答える
0

スクリプトを作成し、sed (ストリーム エディター) を使用して特定のストリームを編集します。

于 2012-04-19T09:52:56.893 に答える