Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I created a ofstream file.
How can I write to the beginning of current line on my file?
For example: I write:
a b c d e f
and now I want to add to the beginning the number of my letters (6) like this:
6 a b c d e f
You have to read the whole file in a byte array.
Then you write your "prefix" followed by you write the byte array to a tmp file.
Finally you have to delete the original file and rename the tmp file.
If you want to write at the beginning of an arbitrary line then you should read the whole file in an array of arrays of bytes, append your prefix to the line you want to edit and finally overwrite the original file.
HINT:-
If it is a text file then the best solution would be to flush the old contents into a temporary location, write what you need and append the old contents
Files are pretty static and don't support adding characters anywhere except at the end. If you need to add characters elsewhere, you need to rewrite the file. Also, files don't really have a concept of lines.
What you could do is recording the position of the file at the beginning of the line (using file.tellp()), write a couple of placeholders (e.g., spaces), and then the rest of the line. Once the line is complete, you'd reposition the write position (using file.seekp()) and overwrite some of the placeholders.
Personally, I wouldn't do anything like that! Instead, I would format the line into a std::ostringstream and, once completed write the line start information followed by the firmatted line (obtained from the std::ostringstream using str()). Well, ideally I'd write the information in one sequence directly to the file if it is readily available.
Files are essentially a stream of bytes that start at a specific location. The only way to insert new data in the front (or in the middle) of a file is to move the data that is after it. Since you are expecting to rewrite the first line, that would mean you would need to read the entire file, prepend your new data, and write out the entire (new) file over the existing one. You can do this with a single std::fstream object, but you will need to reset the file cursor to the beginning after you read the file. It would be more clear to read the file in using an std::ifstream object and then to overwrite the file with an std::ofstream object.
I have on my code:
file << args;
-->here I want to add to the beggining of this line a new argument.. (This argument has information of args But I must write args and after I have the information for the argument)
file << endl;
Related
This question already has answers here:
How to write to middle of a file in C++?
(3 answers)
Closed 6 years ago.
I'm trying to take data from multiple files and append them into one file using fstream, however whenever I try to output to an existing file using
std::ofstream Out("mushroom.csv", std::ofstream::app);
it outputs to the end of the file, I want it to append to the same line, for example if this is the previous file:
1,2,3,4,5,6,7
8,9,10,11,12,13
I want it to become:
1,2,3,4,5,6,7,a,b,c
8,9,10,11,12,13,c,d,e
You can't. Files don't really have lines, they just store a bunch of characters/binary data. When you have
1,2,3,4,5
6,7,8,9,0
It only looks that was because there is an invisible character in there that tells it to write the second line to the second line. The actual data in the file is
1,2,3,4,5\n6,7,8,9,0
So you can see then end of the file is after the 0 and to get after the 5 you would need to seek into the middle of the file.
The way you can get around this is to read each line of the file into some container and then add your data to the end of each line. Then you would write that whole thing back o the file replacing the original contents.
I would like to read a text file in C++ in following manner:
Ignore the entire first line as it is simply meant as an introduction.
Only read the following lines from a specific position.
That starting position for reading is a fixed one and remains the same for every line; however, the numbers after that may be of variable length. I need to save all of these numbers from line 2 to line n into an Array.
At the moment I can read a regular 2D Array with getline.
How can I work around these things?
An example for a line I want to read could be:
Person1: 25 988.3 0.0023 7
To set the file to a position, use std::ifstream::seekg().
To set the file to the beginning of a line, you must read and count the line endings. Many text files have variable length text lines.
How can I work around these things?
You can't, unless you can ensure that all of the data lines after the first line are all the same length.
If you can't ensure that, then all you can do is read through all of the preceding lines.
An alternative I have employed in the past is to generate an 'index' of line start positions in a secondary file in binary format (so that I CAN jump directly to the right place in that file), and use that to jump to the right place in the text file. Of course that means that you need to regenerate that index file every time you replace/amend the data file.
myfile<<hashdugumu[key].numara;
I have this piece of code.For example,i would like to write to eighth line.How do i do that in c++ ?Thanks in advance.
If the line you want to write is exactly the same length (in bytes, not in characters, remember some encodings (like e.g. UTF-8) is variable length) then it's very easy: Just skip over the first seven lines and then write the line.
There is a caveat with this though: input streams and output streams have different stream positions. So if you read from a combined input/output file stream then only the read position will change, so if you just try to write directly then you will not write at the same position. To solve this you need to get the read position, and set the write position to the same value.
As an alternative, or if the data you want to write is not the same size as the existing data, then you have to use a temporary "buffer", be it another file or an actual in-memory buffer.
If the file is not big you can use an in-memory buffer, for example using a std::vector for the lines. Read each line into the vector, and then modify the lines (elements in the vector) that you want to modify. Finally reopen the file for writing, truncating it, and then just write each "line" to the file.
There is a slight problem with the above though when it comes to the rewriting of the data, and that is if the file is truncated and then there's an error when you write to the file, you can lose data. This can be dsolved by using a temporary file.
Using a temporary file it's easier to not bother with the in-memory buffer, and instead read from the original file and write directly to the temporary file. Knowing when you should write something else is done by keeping track of the current line numbers, which is easy if you read one line at a time. In your example you read the first seven lines from the original file and write them to the temporary file, after the seventh line you write your special eight line while skipping the original eight line from the original file, and then just continue reading/writing the remaining lines. When done close the files and then rename the temporary file as the original file.
I am trying to run a program to replace certain data within a file. The relevant parts of the file attempting to be replaced look like the following:
1 Information 15e+10
2 Information 2e+16
3 Information 6e+2
And so on.
The files in question can be very large in the multiple gigabyte range and to my understanding because of this using a buffer of the whole file and rewriting the whole file is impossible/unreasonable. Well that is all fine I just want to replace the values (ex. the 15e+10).
This all works fine with simple ios::in|ios::out and tellp() if I am replacing the value with a similar sized value (15e+10->12e+12) or even if its a smaller size as I can simply add an extra space which can be ignored down the line (ex. 15e+10->4e+10 ). But I am running into the problem if I need to replace the value with a value whose length is longer than already in the file (ex. 6e+2->16e+10) it will write over the new line character or start writing over the information in the next line.
I have searched on the forums and everyone says you can either overwrite in the file, you can append to the end of the file, or you can buffer and recreate the whole file. Is there anyway I can achieve my goal of overwriting the value correctly without having to recreate the file?
If not then how can I have 2 files open (1 input 1 output) to do this if multiple files in question are too large for the memory?
Note: I would also like to avoid using boost:: as I need to be able to run this on a system without the boost library.
Open a stream to read from the input (IN) file and a second stream (OUT) to write to a new output (tmp) file.
Read from IN and write to OUT. When you get a value from IN that you want to replace write the replacement to OUT instead of the value you got from IN.
When parsing is complete replace the first file with the second (tmp) file.
Would this work for you?
Use lseek()/fseek() for "jump" to a given position in a file.
You can use seekp to go to the location and rewrite it with <<
Example:
example.txt ( |?| = 1 byte of data )
|A|B|C|\n|1|2|3|D|E|F|\n|4|5|6|
//Somewhere in the code
fstream file;
open("example.txt");
//Somehow find the character distance and store it into "distance"
seekp(distance);//If distance = 0, it will go to "A" like rewind() but easier for me
If the distance is 4, the next character will be overwritten is 1
file << "987";
And the file will be
|A|B|C|\n|9|8|7|D|E|F|\n|4|5|6|
BUT the only problem here is when you need to increase/decrease the size:
Increase:
You will overwrite the other character so you need to create a temp string to store it the rest of data or separate it into smaller chunk if the data is too large like
|A|B|C|\n|9|8|7|D|E|F|\n|4|5|6|
string tempstring;
seekp(distance);
file >> tempstring;
seekp(distance);
file << content << tempstring; //content is the data
Decrease:
The easiest solution is to write NULL character \0 to the excess space like
|A|B|C|\n|1|\0|\0|D|E|F|\n|4|5|6|
The only side-effect is the file size is the same as before
Is there a way that I can seek to a certain line in a file to read or write data?
Let's say I want to write some data starting on the 10th line in a text file. There might be some data already in the first few lines, or the file could even be empty. Is there a way I can seek directly to the line I want without having to worry about what's already in the file?
Only if the lines are all the same length (seek to 9 * bytes_per_line). Otherwise, you'll just have to scan your way to the appropriate spot in the file.
Also be wary of writing into the middle of a file. It may not do what you expect (insert new lines). It will simply overwrite whatever content is already there, and won't respect existing line boundaries.
You can seek to a position in a file, but that position must be a character offset from the start, end or current position - see for example fseek(). There is no way of seeking to a particular line, unless all the lines are exactly the same length.
No, you have to process the data to find the line delimiters (unless you have fixed length lines). Have a look at getline(), ftell() and fseek(). http://www.pixelbeat.org/programming/readline/cpp.cpp
The easy best way is to read the file in memory inserting for instance each line in a vector of strings, then modifying/adding whatever you want, and re-write each line in a new file.
(supposing the file fits in memory)