Remove parts of text file C++ - 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" ) );

Related

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

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 << ' ';
}

How to push into values into a stack from a text file

I am trying to teach myself C++ with some programming assignments.
Trying to learn using stacks but I am unsure how to push values from a txt file into a stack.
Let' say I have the following text file:
16 24 25 3 20 18 7 17 4 15 13 22 2 12 10 5 8 1 11 21 19 6 23 9 14
How would I use ifstream,and argv from the command line to push the values into a stack?
Did research and using this as help, but it may not be relevant:
How to push data of different data types into a vector by reading from a file?
Here is something to get you started.
stack<int> data;
{
ifstream file("file.txt");
int i;
while (file >> i)
{
data.push_back(i);
}
}

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;
}

Passing non integer input through console

I have this code :
int obj;
while ( std::cin >> obj )
{
std::cout << obj << std::endl ;
int temp = obj ;
++ temp;
std::cout << temp << std::endl ;
}
When I give proper integer inputs, I understand the output.
eg. If I get 12 as input, I see something like this on console :
12
12
13
But, if I give some integers with white spaces as input, I can't seem to understand the output.
eg. If I give 12 12 12 12 as input, I see this on console :
12 12 12 12
12
13
12
13
12
13
12
13
Can someone please explain ?
The first example includes your input.
input
12
output
12
13
The second example is exactly this, multiplied 4 times, for each of the 4 numbers received as input. The seperator is "whitespace" - spaces, new lines or tabs. It is not a "non integer", but rather "four integers":
The input:
12 12 12 12
is equivalent to
12
12
12
12
output:
12
13
12
13
12
13
12
13
The loop reads whatever the input is, only after you hit "enter". So in the first case, it reads one value 12, prints 12 then 13 for the updated value in temp, then goes back waiting for you to type more numbers.
In the second case, it reads 12, prints 12 & 13, then goes back, reads another 12, prints 12 & 13, and so on another 2 times. Then goes back waiting for your to type more data.
Note that whitespace is a proper separator for your input. If you want it to go wrong, try typing 12a, in which case it will print 12 & 13 forever (well, until you get bored and stop it), since it will "stop reading" at the 'a' without updating obj - and because nothing in the loop clears out the a, it keeps going.
When you add the space, it takes them as separate values. And run the while loop for each of them.
int obj;
cin >> obj;
cin reads valid integer data from your input until it finds a character that does not belong to an integer, or there is no more data. In your first example, cin hits the end of your input and returns the number. In your second example, cin reads the input from the string "12 12 12 12", extracts the first integer from your input stream and writes it to obj. In the next run of your while loop, cin is confronted with the string "12 12 12" (since it has extracted/removed the first number from your input stream) and the story continues until there is no more input to read from.

C++ input data into a struct variables from data file

I have a text file containing names and numbers. The name or the string contains 15 chars and I need to put it to the string. I'm working with structures.
struct grybautojas{
string vardas;
int barav, raudon, lep, diena;
}gryb[100];
After that, there are simple calculations which is done right, the problem is, it only reads everything once. After taking a first "box" of information, it just stops. Everything else in the result file is either blank as a string or 0 as an integer.
Here's my input function:
void ivedimas(){
char eil[16];
int b,r,l;
inFile >> n;
inFile.ignore();
for(int i=0;i<n;i++){
inFile.get(eil,15);
gryb[i].vardas=eil;
inFile >> gryb[i].diena;
gryb[i].barav=0, gryb[i].raudon=0, gryb[i].lep=0;
for(int m=0;m<gryb[i].diena;m++){
inFile >> b >> r >> l;
gryb[i].barav+=b, gryb[i].raudon+=r, gryb[i].lep+=l;
}
inFile.ignore();
}
inFile.close();
}
And here's the file containing data:
4
Petras 3
5 13 8
4 0 5
16 1 0
Algis 1
9 6 13
Jurgis 4
4 14 2
4 4 15
16 15 251
1 2 3
Rita 2
6 65 4
4 4 13
What's the problem?
inFile.get(eil,15);
Rita 2
Petras 3
00000000011111
12345678901234
I don't count 15, I count 14. Also, some of your lines seem to have a space at the end. You should rewrite your input logic to be much more robust. Read lines and parse them.
This line:
inFile.get(eil,15);
is reading the number that follows the name.
When you try to read the number (3 in your example), you get the next one (5) instead.