编辑文件中的特定行

时间:2012-04-19 09:25:02

标签: c

我有一个这样的txt文件:

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

我需要编辑夹克的数量(例如26到42)。 所以,我已经编写了这段代码,但我不知道如何编辑一个特定的行,其中有“jacket”这个词:

#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;
}

5 个答案:

答案 0 :(得分:5)

不幸的是,没有简单的解决方案。

一种常见的方法是将所有行(已修改或未修改)写入临时文件,然后将临时文件移动到现有文件上。

答案 1 :(得分: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个项目。如果您进行了这样的更改,则需要更改上面的代码以检查和调整空格数等。

答案 2 :(得分:0)

文本文件不像数据库,我们可以在一次性修改单行或列,在c / c ++中也很难以重复编码为代价。

答案 3 :(得分:0)

编写脚本并使用sed(流编辑器)编辑特定的流。

答案 4 :(得分: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;
}