Editar una fila específica en un archivo

Tengo un archivo de texto como este:

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

Necesito editar el número de chaqueta (de 26 a 42 por ejemplo). Entonces, escribí este código, pero no sé cómo editar una fila específica donde está la palabra “chaqueta”:

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

Desafortunadamente no hay una solución fácil para esto.

Un método común es escribir todas las líneas (modificadas o no) en un archivo temporal y luego mover el archivo temporal sobre el archivo existente.

Si el número de caracteres en el valor antiguo y nuevo es el mismo (su caso), puede sobrescribirlos:

 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); 

Es posible que desee cambiar el formato de archivo para incluir el relleno, por ejemplo:

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

Aquí _ visualiza un personaje espacial; este formato de archivo admite un máximo de 999999 elementos. Si realiza tal cambio, necesita cambiar el código anterior para verificar y ajustar el número de espacios, etc.

Los archivos de texto no son como una base de datos donde podemos modificar una sola fila o columna en una sola toma que también en c / c ++ es muy difícil porque tiene un costo de encoding duplicada.

Escriba un script y use sed (editor de secuencias) para editar una secuencia específica.

Es probable que sea más fácil usar 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 } } 

Si realmente quisiera hacerlo en c, podría usar la función 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; }