How to insert text in an existing file? [duplicate] - c++

This question already has answers here:
How to write to middle of a file in C++?
(3 answers)
Closed 5 years ago.
Example, I have a sample.txt file with content:
1 2 3 7 8 9 10
and I want to insert 4 5 6in file to have
1 2 3 4 5 6 7 8 9 10
so that numbers are inserted in the right place.

Files generally don't support inserting text in the middle. You should read the file, update the contents and overwrite the file.
Use a sorted container, e.g. std::set to hold the contents of the file in memory.
std::set<int> contents;
// Read the file
{
std::ifstream input("file");
int i;
while (input >> i)
contents.insert(i);
}
// Insert stuff
contents.insert(4);
contents.insert(5);
contents.insert(6);
// Write the file
{
std::ofstream output("file");
for (int i: contents)
output << i << ' ';
}

Related

Confused by how stringstream seems to work [duplicate]

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 6 months ago.
I'm new to c++. Currently I'm learning how to read and write to a file. I've created a file "nb.txt" with content like this:
1 2 3 4 5 6 7
2 3 4 5 6 7 9
I'm using a simple program to read this file, looping until reached EOF.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream in("nb.txt");
while (in) {
int current;
in >> current;
cout << current << " ";
}
}
What I'm expecting is the program will output all of the values.
But what I'm really getting is this:
1 2 3 4 5 6 7 2 3 4 5 6 7 9 9
There's a multiple "9" in the output. I don't understand what's happening! Is it because of the while loop?
Can anyone help me to figure out why there is another "9"? Thanks!
The problem is that after you read the last value(which is 9 in this case) in is not yet set to end of file. So the program enters the while loop one more time, then reads in(which now sets it to end of file) and no changes are made to the variable current and it is printed with its current value(which is 9).
To solve this problem, you can do the following:
int main() {
ifstream in("nb.txt");
int current=0;
while (in >> current) { //note the in >> curent
cout << current << " ";
}
}
The output of the above program can be seen here:
1 2 3 4 5 6 7 2 3 4 5 6 7 9

How to read data from input txt file into 2 C++ arrays?

The txt file
1 2 3 4 5 col A
2 3 4 5 6 col B
2 3 4 5 6 col C
2 3 4 5 6 col D
2 3 4 5 6 col E
I already know how to store the numbers into 2d array. However, the question also require me to store the words (including the space) into a one-dimensional array. Can somebody tell me how to do this? I am new to C++. Any help will be appreciated.
This would require a basic reading file loop which will read the file line by line, then split it by spaces. For the number it pushes it to the 2d array and the words to a 1d array:
fstream file;
file.open("somefile.txt");
vector<vector<double>> nums;
vector<string> words;
string line;
while(getline(file, line))
{
vector<double> tempNums;
istringstream liney(line); int i = 0; string cell;
while(getline(liney, cell, ' '))
{
if(i < 5) tempNums.push_back(stoi(cell.c_str()));
else words.push_back(" " + cell);
i++;
}
nums.push_back(tempNums)
}
Hope this helps. (This is based on the formatting above)

How can I read a file and split each line in C++? [duplicate]

This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 7 years ago.
I have a file like this:
4 88 101
1 22 100
6 41 151
I have 3 arrays and i want to put the first values(4, 1, 6) to my first array, the second values(88, 22, 41) to my second array etc.
So how can I split each line by space??
I have already read the file but I cannot fill my arrays with these values.
If you know the exact number of items per line of data from the file, you can open it with an ifstream and do:
int firstNum, secondNum, thirdNum;
while (inFile >> firstNum >> secondNum >> thirdNum)
{
//do something
}

Remove parts of text file C++

I have a text file called copynumbers.txt that I need to delete some numbers after a number while using Example would be a text file containing the following
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
each integer should occupy 4 byte spaces.
I want to delete or get rid of number 7 to 15 while keeping 1 through 6 then adding the number 30 to it.
so then the file would keep 1 to 6 and get rid of 7 to 15 then after that I want to at 30 at the end of it.
my new file should look like this
1 2 3 4 5 6 30
my question is how would I do that without overriding the number 1 to 6?
because when I use
std::ofstream outfile;
outfile.open ("copynumbers.txt");
it will override everything and leave only 30 in the file
and when I use
ofstream outfile("copynumbers.txt", ios::app);
It will just append 30 after 15 but does not delete anything.
Some of my code:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream outfile("copynumbers.txt", ios::app);
outfile.seekp(0, outfile.end);
int position = outfile.tellp();
cout << position;
//outfile.seekp(position - 35);
outfile.seekp(28);
outfile.write(" 30",4);
outfile.close();
return 0;
}
It's generally a bad idea to try to modify a file "in place" - if anything goes wrong then you end up with a corrupted or lost file. Typically you would do something like this:
open original file for input
create temporary file for output
read input file, process, write to temporary file
if successful then:
delete original file
rename temporary file to original file name
As well as being a safer strategy, this makes the process of modifying the contents easier, e.g. to "delete" something from the file you just skip over that part when reading the input (i.e. just don't write that part to the output file).
You have to use seekp function. Check this out.
http://www.cplusplus.com/reference/ostream/ostream/seekp/
I would recommend read the original file in memory,make the required changes in memory and then write everything out to the file from scratch.
Would a std::istream_iterator help you here?
If you know you just want the first 6 words you can do something like this:
std::istringstream input( " 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" );
std::vector< int > output( 7, 30 ); // initialize everything to 30
std::copy_n( std::istream_iterator< int >( input ), 6, output.begin() ); // Overwrite the first 6 characters
If you wanted your output tab separated you could do something like this for output:
std::ofstream outfile( "copynumbers.txt" );
outfile << '\t';
std::copy( outfile.begin(), outfile.end(), std::ostream_iterator< int >( outfile, "\t" ) );

Reading in an unknown number of integers separated by spaces into one vector per line

Each line of my file consists of an unknown number of integers, which are separated by spaces. I would like to read in each line as a vector of those integers.
Here is an example of such file:
11 3 0 1
4 5 0 3
2 3 4 1
23 4 25 15 11
0 2 6 7 10
5 6 2
1
11
I've been able to read in small amounts of data successfully using the following method (Note that outer_layers is a vector that contains these vectors I'm trying to populate):
for (int i = 0; i < outer_layers.size(); i++)
{
while (in >> temp_num)
{
outer_layers[i].inner_layer.push_back(temp_num);
if (in.peek() == '\n')
break;
}
}
However, when I'm trying to read in larger amounts of data, sometimes it'll read in two lines under one vector. In one of the files, out of 24 lines, it read two-liners on two occasions, so last two vectors did not have any data.
I can't wrap my head around it. Any ideas what I'm doing wrong?
EDIT: Something interesting I've noticed in some of the lines of the trouble-maker file is this:
Let's say there are three lines.
23 42 1 5
1 0 5 10
2 3 11
Line #1 reads in just fine as 23 42 1 5; however, line #2 and #3 get read together as 1 0 5 10 2 3 11.
In Notepad++ they look just fine, each on their own lines. However, in Notepad, they look like this:
23 42 1 51 0 5 10 2 3 11
If you notice, the 5 (last integer of line #1) and 1 (first integer of line #2) are not separated by spaces; however, 10 and 2 are separated by a space.
I've noticed that behavior on any double-read-in lines. If they are separated by a space, then they're both read in. Not sure why this is occurring, considering there should still be a new line character in there for Notepad++ to display the on separate lines, am I right?
I'm not sure how your outer_layers and inner_layers is setup, but you can use std::getline and std::stringstream to fill your vectors something like this :
std::vector< std::vector<int> > V ;
std::vector <int> vec;
std::ifstream fin("input.txt");
std::string line;
int i;
while (std::getline( fin, line) ) //Read a line
{
std::stringstream ss(line);
while(ss >> i) //Extract integers from line
vec.push_back(i);
V.push_back(vec);
vec.clear();
}
fin.close();
for(const auto &x:V)
{
for(const auto &y:x)
std::cout<<y<<" ";
std::cout<<std::endl;
}