Inserting data to file in c - c

I need to add a string before the 45th byte in an existing file. I tried using fseek as shown below.
int main()
{
FILE *fp;
char str[] = "test";
fp = fopen(FILEPATH,"a");
fseek(fp,-45, SEEK_END);
fprintf(fp,"%s",str);
fclose(fp);
return(0);
}
I expected that this code will add "test" before the 45th char from EOF, instead, it just appends "test" to the EOF.
Please help me to find the solution.
This is continuation of my previous question
Append item to a file before last line in c

Open it with mode r+ (if it already exists) or a+ (if it doesn't exist and you want to create it). Since you're seeking to 45 bytes before the end of file, I'm assuming it already exists.
fp = fopen(FILEPATH,"r+");
The rest of your code is fine. Also note that this will not insert the text, but will overwrite whatever is currently at that position in the file.
ie, if your file looks like this:
xxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx
Then after running this code, it will look like this:
xxxxxxxtestxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx
If you really want to insert and not overwrite, then you need to read all the text from SEEK_END-45 to EOF into memory, write test and then write the text back

Don't open it as append (a) if you plan to write at arbitrary positions; it will force all writes to the end of the file. You can use r+ to read or write anywhere.

To avoid platform-specific configurations, always explicitely indicate the binary or text mode in your fopen() call.
This will save you hours of desperations if you port your code one day.

Related

C - Using fgetc on a write file

Say we have a file pointer like this:
FILE *output = fopen("test.out", "w");
After writing to it, I want to read it using fgetc
However when I do:
char c1 = fgetc(output);
and then I print out c1 I get that c1 equals -1 which means there was an error in fgetc. Is it because I opened the file using "w"?
How can I read and write from the same file in the same function?
If you want to be able to both read and write the file, you should open it in write/update mode (ie pass “w+” to the mode argument instead of just “w”)
Also be sure to do a frewind() or fseek() before trying to read from the file, otherwise you’ll be trying to read past the end of the file’s data.
You can't read from a write-only file. Open the file for read/write access using "w+" instead.
Also, after you write to the file, you have to seek backwards with fseek() before you can then read what you previously wrote.

Reading a string from a file with C. Fopen with w+ mode is not working

I made a C program that reads a string from a .txt file, then it encrypts the string, and finally it writes the string in the same file.
The thing is that if I use fopen("D:\\Prueba.txt","w+"), the program doesn't work, it prints garbage like this )PHI N.
I've debugged and I know the error is there in that line, because if I use fopen("D:\\Prueba.txt","r+"), the program works, and it writes what it should.
But I want to use w+ because it will rewrite what the .txt file had. Why is w+ not working?
If you're opening with w+ to first read the content, that's not going to work. From C11:
w+: truncate to zero length or create text file for update.
What's probably happening is that you read data from the now empty file but don't correctly check that it worked. That would explain the weird "content" you see of )PHI N.
One solution is to open the file as with r, open another file with w, and transfer the contents, encrypting them as part of that process. Then close both, delete the original, and rename the new one to the original name. This will allow you to process arbitrarily-sized files since you process them a bit at a time.
If you don't want to use a temporary file, and you're sure you can store the entire content in memory, you could open it r+, get the content, the reopen it with a new mode, such as with:
FILE *readFh = fopen( "myfile.txt", "r+");
// Read in content, massage as needed.
FILE *writeFh = frepoen( NULL, "w+", readFh);
// Provided that worked, you should now have an empty file to write to.
// Write back your massaged data.

Inserting text in a file instead of overwriting in c

How can I insert characters in a file using C instead of overwriting? I also want to write in start of file and end of a file. I tried this method but it didn't work out (I can re-position but I cannot insert. The text is overwritten)
I've tried this, but it didn't work:
fword = fopen("wrote.txt", "rb+");
fseek(fword, 0, SEEK_SET);
fscanf(fword, "%c", &l);
To add text at the end, you can open the file with "a" mode (check the fopen manual). It will write your text to end.
To add text in other positions, you have to read everything after that to memory, write what you want and then write the rest.
Files are abstractions of byte streams, there is no such concept as insert in a byte stream, you can seek into certain place and write data there. The bytes you wrote will lay in the file as an array of bytes, if the writing exceeds the current file size, the file will be extended.

problem writing in file

FILE *ExcelFile = fopen("testdata.csv","w");
if (ExcelFile == NULL)
return -1;
fprintf(ExcelFile,"1 2 3");
fprintf(ExcelFile,"\n");
fclose(ExcelFile);
//==============================================
FILE *fa = fopen("testdata.csv","w");
if (fa == NULL)
return -1;
fseek (fa, 6 , SEEK_SET );
fprintf(ExcelFile,"a");
fclose(fa);
in the code i have write 1 2 3 in the file and also inserted '\n' (required for the program) now i want to place a after 3 like 1 2 3 a but hte problem iam facing is that my code erase all char an simply write a . help required .thanks
First of all, a CSV file should have "comma separated values", as the name indicates. So, rather than "1 2 3", you'd better have "1,2,3" or "1;2;3".
Now, there are multiple ways of opening a file : you're only using the "w" as "writing" mode. When you're in writing mode, you're erasing your file. You could use the "a" as "add" mode, which mean that everything will be put after it.
You could also :
1°) First read your file with a "r" mode and store it in memory. Then, close it.
2°) Then, open your file with a "w" mode, copy what you stored, and then make your addendum. Then, close it.
(There is a "reading and writing mode" too, check the link provided by another answer ; but this solution can easily be broken in small pieces, to have small functions doing each their part of the job).
Every time you open your file, you are opening it as a 'w' option. In C, this has a specific meaning : start writing at the beginning of the file.
For your first write of the file, this is okay, but for every subsequent write, you're overwriting your previous content.
Solution Use the 'a' attribute instead here. Like this:
FILE *fa = fopen("testdata.csv","a");
See more information about fopen here...
EDIT
Reading your comments, I understand that when you write again, the next thing starts on a new line. This is because of your initial write 1 2 3 \n (The \n makes a new line).
To correct this you can :
Don't write a '\n' at all.
OR
Read the entire file first, rewrite it without the \n and then write your new a and \n
You want mode "r+". Using mode "a", all writes will go to the end of the file.
You specified w for fopen(), which means "create the file or open for overwrite if already exists".
Therefore, your second call to fopen() cleared the file's contents.
Use a, for: "create the file, or append to it if already exists".
fopen (filename,"a")
a = append

Seeking to beginning of file

I have a small code block that should append text to the beg of a file. However it still only adds to the end of the file. I thought the rewind set the pointer to the front of the file, thus when I added the text using fprintf it should add to the front. How can I change this?
fp = fopen("Data.txt", "a");
rewind(fp);
fprintf(fp, "%s\n", text);
fclose(fp);
Text is a char array to be added at the front of the file
1) Don't open in append mode.
When you open in append mode, all writes go to the end of the file, regardless of the seek position.
http://www.opengroup.org/onlinepubs/009695399/functions/fopen.html
Opening a file with append mode (a as
the first character in the mode
argument) shall cause all subsequent
writes to the file to be forced to the
then current end-of-file, regardless
of intervening calls to fseek().
2) Opening without "a" still won't do what you want. It's not possible to insert into a file using the ANSI/POSIX file operations, because given the way most file systems store their data, insert is not a simple operation.
You need either to open a new file, write your new data, then append the old file afterwards, or else you need to mess around shuffling data forward in blocks. Either option is very inefficient for large files, compared with appending at the end, not to mention error-prone if you need the program or the machine to be able to unexpectedly die without corrupting data. So if this is a log file or similar, it's probably worth redesigning so that you can write new data to the end, and then reverse it all when you prepare a report from the log.
You can replace data in a file, but you can't prepend or insert it anywhere but at the very end of the file.
Just create a new file with your data and then append the old data in this file you created.

Resources