编辑文件中的特定行
我有一个这样的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; }