How to write at the middle of a file in c - c

Is it possible to write at the middle of a file for example I want to insert some string at the 5th position in the 2nd line of a file in c ?
I'm not very familiar with some of C functions that are related to handling files , if someone could help me I would appreciate it
I tried using fputs but I couldn't insert characters at the desired location

open a new output file
read the input file line by line (fgets) writing each line out to a new file as you read.
When you hit the place you want to insert write the new line(s)
The carry on copy the old lines to the new file
close input and output
rename output file to input

Continuing from my comments above. Here's what I'd do:
Create two large, static char[] buffers of the same size--each large enough to store the largest file you could possibly ever need to read in (ex: 10 MiB). Ex:
#define MAX_FILE_SIZE_10_MIB (10*1024*1024)
static char buffer_file_in[MAX_FILE_SIZE_10_MIB];
static char buffer_file_out[MAX_FILE_SIZE_10_MIB];
Use fopen(filename, "r+") to open the file as read/update. See: https://cplusplus.com/reference/cstdio/fopen/. Read the chars one-by-one using fgetc() (see my file_load() function for how to use fgetc()) into the first large char buffer you created, buffer_file_in. Continue until you've read the whole file into that buffer.
Find the location of the place you'd like to do the insertion. Note: you could do this live as you read the file into buffer_file_in the first time by counting newline chars ('\n') to see what line you are on. Copy chars from buffer_file_in to buffer_file_out up to that point. Now, write your new contents into buffer_file_out at that point. Then, finish copying the rest of buffer_file_in into buffer_file_out after your inserted chars.
Seek to the beginning of the file with fseek(file_pointer, 0, SEEK_SET);
Write the buffer_file_out buffer contents into the file with fwrite().
Close the file with fclose().
There are some optimizations you could do here, such as storing the index where you want to begin your insertion, and not copying the chars up to that point into buffer_file_in, but rather, simply copying the remaining of the file after that into buffer_file_in, and then seeking to that point later and writing only your new contents plus the rest of the file. This avoids unnecessarily rewriting the very beginning of the fie prior to the insertion point is all.
(Probably preferred) you could also just copy the file and the changes you insert straight into buffer_file_out in one shot, then write that back to the file starting at the beginning of the file. This would be very similar to #pm100's approach, except using 1 file + 1 buffer rather than 2 files.
Look for other optimizations and reductions of redundancy as applicable.
My approach above uses 1 file and 1 or 2 buffers in RAM, depending on implementation. #pm100's approach uses 2 files and 0 buffers in RAM (very similar to what my 1 file and 1 buffer approach would look like), depending on implementation. Both approaches are valid.

Related

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.

replace a substring in a string in C, windows

I want to do the following:
open and read and ASCII file
locate a substring (geographical coordinates)
create its replacement (apply corrections to the original coordinates)
overwrite the original substring (write in the original file the corrected coordinates).
The format of the ASCII file is:
$GPGGA,091306.00,4548.17420,N,00905.47990,E,1,09,0.87,233.5,M,47.2,M,,*53
I will paste here only the part of the code that is responsible for this operation:
opnmea = fopen (argv[1], "r+");
if (fgets(row_nmea, ROW, opnmea)==NULL){
if (strstr(row_nmea,"$GPGGA")!=NULL) {
sscanf(row_nmea+17, "%10c", old_phi);
sscanf(row_nmea+30, "%11c", old_lam);
sscanf(row_nmea+54, "%5c", old_h);
fputs();
}
}
What I do till now is to extract in a variable the old coordinates and I was thinking to use fputs() for overwriting the old with new values. But I could not do it. The other part of the code that is not here is computing the correct coordinates. My idea is to correct the rows one by one, as the fgets() function reads each line.
I would appreciate very much any suggestion that can show me how to use fputs() or another function to complete my work. I am looking for something simple as I am beginner with C.
Thank you in advance.
Patching a text file in place is not a good solution for this problem, for multiple reasons:
the modified version might have a different length, hence patching cannot be done in place.
the read-write operation of standard streams is not so easy to handle correctly and defeats the buffering mechanism.
if you encounter an error during the patching phase, a partially modified file can be considered corrupted as one cannot tell which coordinates have been modified and which have not.
other programs might be reading from the same file as you are writing it. They will read invalid or inconsistent data.
I strongly recommend to write a program that reads the original file and writes a modified version to a different output file.
For this you need to:
open the original file for reading opnmea = fopen(argv[1], "r");
open the output file for writing: outfile = fopen(temporary_file_name, "w");
copy the lines that do not require modification: just call fputs(row_nmea, outfile).
parse relevant data in lines that require modification with whatever method you are comfortable with: sscanf, strtok, ...
compute the modified fields and write the modified line to outfile with fprintf.
Once the file has been completely and correctly handled, you can replace the original file with rename. The rename operation is usually atomic at the file-system level, so other programs will either finish reading from the previous version or open the new version.
Of course, if the file has only one line, you could simply rewind the stream and write back the line with fprintf, but this is a special case and it will fail if the new version is shorter than the original. Truncating the extra data is not easy. An alternative is to reopen the file in write mode ("w") before writing the modified line.
I would recommend strtok(), followed by your revision, followed by strcat().
strtok() will let you separate the line using the comma as a delimiter, so you will get the field you want reliably. You can break up the line into separate strings, revise the coordinates you wish, and reassemble the line, including the commas, with strcat().
These pages include nice usage examples, too:
http://www.cplusplus.com/reference/cstring/strtok/
http://www.cplusplus.com/reference/cstring/strcat/?kw=strcat

C - dynamically modifying a file - is it possible?

I'm writing a small program in C and I want to have the option of saving data to file and then reading it from that file. The data is BIG, so I want to somehow dynamically write to a file without having to create a new file and copy modified old file into it.
Here's exactly what I want to do:
In the first line, I want to have "description" of the data in the form "%s %s %s ... %s \n" where %s is a string and the n'th string describes data in n+1'th line. I want to read the 1'st line of the file, scan for corresponding "description" string, and if it is not present, append it to the first line, and the data corresponding to it after the last line of the file.
The question is - is it possible to "jump" into lines in the file without scanning all the previous lines, and can I somehow read the first line of the file and append something to it after reading? Or maybe it is not the way to go in this situation and C offers some kind of different solution?
What you want can be done using stdio and fseek(). As long as you know at what byte offset you want to go, you can overwrite and/or append anywhere in the file without reading the data before, or the data you're overwriting. What you can not easily do is insert data, i.e., open the file, split it in half and put data in between.
Not too sure if that is what you mean though...

How to read from a specific line from a text file in VHDL

I am doing a program in VHDL to read and write data. My program has to read data from a line, process it, and then save the new value in the old position. My code is somewhat like:
WRITE_FILE: process (CLK)
variable VEC_LINE : line;
file VEC_FILE : text is out "results";
begin
if CLK='0' then
write (VEC_LINE, OUT_DATA);
writeline (VEC_FILE, VEC_LINE);
end if;
end process WRITE_FILE;
If I want to read line 15, how can I specify that? Then I want to clear line 15 and have to write a new data there. The LINE is of access type, will it accept integer values?
Russell's answer - using two files - is the answer.
There isn't a good way to find the 15th line (seek) but for VHDL's purpose, reading and discarding the first 14 lines is perfectly adequate. Just wrap it in a procedure named "seek" and carry on!
If you're on the 17th line already, you can't seek backwards, or rewind to the beginning. What you can do is flush the output file (save the open line, copy the rest of the input file to it, close both files and reopen them. Naturally, this requires VHDL-93 not VHDL-87 syntax for file operations). Just wrap that in a procedure called "rewind", and carry on!
Keep track of the current line number, and now you can seek to line 15, wherever you are.
It's not pretty and it's not fast, but it'll work just fine. And that's good enough for VHDL's purposes.
In other words you can write a text editor in VHDL if you must, (ignoring the problem of interactive input, though reading stdin should work) but there are much better languages for the job. One of them even looks a lot like an object-oriented VHDL...
Use 2 files, an input file and an output file.
file_open(vectors, "stimulus/input_vectors.txt", read_mode);
file_open(results, "stimulus/output_results.txt", write_mode);
while not endfile(vectors) loop
readline(vectors, iline);
read(iline, a_in);
etc for all your input data...
write(oline, <output data>
end loop;
file_close(vectors);
file_close(results);

is there any basic way to delete something from opened file

When you open a .txt file with fopen
Is there any way to delete some strings in a file without rewriting.
For example this is the txt file that i will open with fopen() ;
-------------
1 some string
2 SOME string
3 some STRING
-------------
i want to delete the line which's first character is 2 and change it into
-------------
1 some string
3 some STRING
-------------
My solution is;
First read all data and keep them in string variables. Then fopen the same file with w mode. And write the data again except line 2. (But this is not logical i am searching for an easier way in C ...)
(i hope my english wasn't problem)
The easiest way might be to memory-map the whole file using mmap. With mmap you get access to the file as a long memory buffer that you can modify with changes being reflected on disk. Then you can find the offset of that line and move the whole tail of the file that many bytes back to overwrite the line.
you should not overwrite the file, better is to open another (temp)-file, write contents inside and then delete old file and rename the file. So it is safer if problems occur.
I think the easiest way is to
read whole file
modify contents in memory
write back to a temp file
delete original file
rename temp file to original file
Sounds not too illogical to me..
For sequential files, no matter what technique you use to delete line 2, you still have to write the file back to disk.

Resources