编辑文件中的特定行

我有一个这样的txt文件:

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

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

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

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

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

如果旧值和新值中的字符数相同(您的情况),则可以覆盖它们:

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

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

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

使用gawk可能更容易。

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

edit_row.awk

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

如果你真的想在c中做,你可以使用tmpfile()函数。

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