Question

I have a file of about 2000 lines of text that i generate in my program, every line has the information of an employee and it's outputed like this

1 1 Isaac Fonseca 58 c 1600 1310.40 6 1 0.22 2164.80 1
2 1 Manuel Gutierrez 22 d 1700 1523.37 4 1 0.13 897.26 1
3 1 Daniel Bernal 34 c 1600 1195.84 2 1 0.26 836.16 1
4 1 Miguel Gonzalez 43 e 1800 1195.84 0 1 0.15 0.00 1

But i whenever i edit an employee information i have to update the file, what i'm doing it's i search for the line and try to rewrite it

I've seen the following question of someone with the same problem, but when i try to write to the file it always writes to the end of file

overwriting a specific line on a text file?

Here is my code:

datos = fopen(archivo,"a+");
for(i=0;i<num;i++){
    // buscar la linea
    fgets(lineaA,100,datos);
    // sobreescribir
    if(i == (num-1))
        cursor = ftell(datos);                      
}

cursor -= strlen(lineaA) - 1;
fseek(datos,cursor,SEEK_CUR);

fputs(linea2,datos);            
fclose(datos);
Was it helpful?

Solution

You pretty much can't do this.

You can use fseek to go to a specific location in a file, and you can write data to that location (you probably want to use "r+" mode).

But a file is typically stored as a sequence of bytes (or characters), not as a sequence of lines.

If you're careful to write exactly the same number of bytes that were already in the line, you can probably get away with it -- but in your example, the lines are of varying lengths, so this isn't an option.

You could, for example, pad each line with blanks, so they're all the same length, but then it's easy to corrupt the layout if you modify the file using, say, an ordinary text editor.

For text files, the usual approach is to read the file into memory, modify the in-memory representation, and then re-create the entire file. You probably want to write the contents to a new temporary file, then rename it after you've confirmed that there were no write errors.

This is what text editors typically do.

(Don't worry too much about efficiency; 2000 lines isn't all that big, and you won't notice the time it takes to write them.)

There are alternatives. You can define a binary format with fixed-length records, or you can use a database. Or you can just append new lines to the file, and treat duplicates as if they had been deleted (but this can cause the file to grow very large if you do a lot of updates).

OTHER TIPS

Unless this is something like homework, where you need to roll all the code on your own, it's probably easiest to switch to a database. Given that you have the rest of the code working, SQLite would probably be the most obvious choice.

If you really want to stick (something at least similar to) your current format and code, I'd probably write the data with each line padded to something like 64 or 128 bytes (and if you have a few records that go longer, isolate them, such as moving all of them to the end of the file, or putting them in a separate file). This way (most?) editing can be done without affecting other lines. If you have the index of the line for an employee, you'll also be able to seek directly to that line instead of reading all its predecessors to find it.

You're opening the file with the option "a+", which only allows you to append to the file, not overwrite. You want to use "r+"

datos = fopen(archivo,"r+);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top