editing a specific line of a file in C
Solution 1
For fopen modes see http://www.cplusplus.com/reference/cstdio/fopen/. I think you need to use the option r+
because you are modifying the file in a random-access way fior both read and write.
"r+" read/update: Open a file for update (both for input and output). The file must exist.
"w+" write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.
"a+" append/update: Open a file for update (both for input and output) with all output operations writing data at the end of the file. Repositioning operations (fseek, fsetpos, rewind) affects the next input operations, but output operations move the position back to the end of file. The file is created if it does not exist.
I would suggest storing the number of lines in the file as an unsigned integer and not a string. The reason is that as a string 0-9 lines take one byte, but the minute you have 10 lines you need two byes, 100, 3 bytes and so on. In each case when an extra character is required you would have to re-write the entire file. I presume this is why you check that number of scores is less than 10.
A better solution would be to keep the first 4 bytes of the file as an unsigned integer and then start the ascii text after.
int result;
uint32_t number_of_scores;
size_t bytesRead;
FILE *data;
...
/* Open a file for update (both for input and output).
* The file must exist. */
data = fopen("highscore.txt","r+");
if( !data )
exit(SOME_ERROR_CODE);
/* Read a 32-bit unsigned integer from the file. NOTE there is no endianess
* "protection" here... ignoring this issue for the sake of simplicity and relevance */
bytesRead = fread (&number_of_scores, sizeof(number_of_scores), 1, data);
if( bytesRead != 1 )
exit(SOME_ERROR_CODE);
/* Seek to end of file */
result = fseek(data, 0, SEEK_END);
if( result )
exit(SOME_ERROR_CODE);
/* Write in the next line */
result = fprintf(data,
"%s %s %s %s\n",
user[current_user].name,
user[current_user].age,
user[current_user].college,
resultVariableRenamedToAvoidNameCollision);
/* Up the number of scores and write it back to the start of the file */
number_of_scores++;
result = fseek(data, 0, SEEK_SET);
if( result )
exit(SOME_ERROR_CODE);
bytesRead = fwrite (data, sizeof(number_of_scores), 1, data);
if( bytesRead != 1 )
exit(SOME_ERROR_CODE);
fclose(data);
Doh, and I've just realised how late this answer is... never mind :S
Solution 2
You need to open the file in read-and-write mode ("r+"
), not append ("a"
). The write position will be at the start, initially, so you might as well update the line count first. Then you can fseek(data, 0, SEEK_END)
before appending your new line.
Nasif Imtiaz Ohi
Updated on June 27, 2022Comments
-
Nasif Imtiaz Ohi almost 2 years
I am facing a problem in C to edit a specific line of a file. There is a number in the beginning of the file which is followed by a number of lines. It kind of looks like this.
2 Nasif 20 BUET 130 Oishi 24 KMC 131
After each execution, I append one more line in the file. And the first number in the file (which actually indicates the number of lines) increases by 1. This process seems not to be working.
data=fopen("highscore.txt","r"); fscanf(data,"%d",&number_of_scores); fclose(data); if(number_of_scores<10){ data=fopen("highscore.txt","a"); fprintf(data,"%s %s %s %s\n", user[current_user].name, user[current_user].age, user[current_user].college,result); number_of_scores++; fseek(data,0,0); fprintf(data,"%d",number_of_scores); fclose(data); } else{ }
So, what should be the right approach?