Textfiles C++ Editing the very first line - c++

Example of Textfile:
5 <- I need to edit this number.
0
1
0
6
(Sample Code Not Whole Program)
#include <fstream>
#include <iostream>
using namespace std;
int main() {
int i;
cin>>i;
std::fstream file("example.txt", std::ios::in | std::ios::out | std::ios::app);
file.seekp(0);
file << i;
return 0;
}
With this code the number is added here:
(example.txt)
5
0
1
0
67 <<
Please note that from the bottom the numbers will keep increasing so it has to be always the first line not that specific 5.
Please Help
Thanks

You have opened the file in a mode that requests that all new data is appended to the end of the file (std::ios::app). Don't specify that flag if you don't want to always append.
Note that you will encounter problems if the new line you're writing is not exactly the same length as the existing line. In the case where it's a different length, you will have to copy and rewrite the entire remainder of the file.

Related

How to remove the extra newline in file handling?

I have written the following code. What I did is this
opened a file "Numbers.dat" and asked input from console
then separated the numbers in separate even and odd files
#include <fstream>
#include <iostream>
int main() {
std::ofstream numWrite("Numbers.dat");
int temp;
while(std::cin>>temp){
numWrite<<temp<<std::endl;
}
numWrite.close();
std::ofstream even("Even.dat"), odd("Odd.dat");
std::ifstream num("Numbers.dat");
while(num){
num>>temp;
if(temp%2==0)
even<<temp<<std::endl;
else
odd<<temp<<std::endl;
}
num.close();
even.close();
odd.close();
return 0;
}
I used newlines after every input, therefore I am having the extra newline in Numbers.dat file and when my program is reading that, it is giving an extra output to the even/odd files.
I can eliminate them by either removing newline from the numbers.dat file, or some check on the other code.
But I am unable to do that, please help!
Or if there is a better way, tell me that too!
Inputs:
1 2 3 4 5 6 7 8 9 10 a
OUTPUTS:
even.dat
2
4
8
10
10
odd.dat
1
3
5
7
9
Problem is this:
while(num){
num>>temp;
This should be done this way:
while(num>>temp){
For details see eof() bad practice?
Fancy way to address this is, by use of iterators and std::partition_copy
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>
int main() {
std::ifstream in("Numbers.dat");
std::ofstream even("Even.dat");
std::ofstream odd("Odd.dat");
std::partition_copy(
std::istream_iterator<int>{in}, {},
std::ostream_iterator<int>{even, " "},
std::ostream_iterator<int>{odd, " "},
[](auto x) { return x % 2 == 0; });
return 0;
}
https://godbolt.org/z/z4qcErPWd

Replacing the data in a specific row in the txt file

I'm building a TCP Server application. Two different types of requests come from the client. In the first request type, the client requests a certain number of line information starting from a certain line. For example, the client throws a request like I want to read 3 lines starting at line 5.It's okay so far, I've completed this part, but now let's come to the part where I have difficulty.In the second type of request, the client wants to change the characters in a certain number of lines starting from a certain line.For example change 4 rows starting at row 6.txt file consists of 1s and 0s.txt file is as follows.
1
0
1
0
1
The txt file should be as follows when two line change requests are received, starting from the fourth line.
1
0
1
1
0
I don't use index numbers to identify line numbers, instead I first read the entire file with a loop and push the read data into a vector at each iteration. Thus, when I want to read a particular line, I call the desired index of that vector.
The parts of the code that interest us are shown below.
std::fstream myfile("fc3-4.txt", std::ios_base::in);
int reg;
std::vector<int> registers_vec;
while (myfile >> reg)
{
registers_vec.push_back(reg);
}
As a result of my research, I found to delete a specific data, but this does not work for me because for example, if I write 1 to the value to be deleted, it deletes all the 1s in the txt file.How can I replace a certain number of rows starting from a certain row as I mentioned above.Thanks in advance
First read the complete file into memory. Then close the file.
Make the modifications in memory.
Then, after modifications have been done, write the complete vector to the file.
E.g.:
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
int main() {
// Open the file and check, if it could be opened
if (std::ifstream dataStream{ "fc3-4.txt" }; dataStream) {
// Read all vallues in vector data
std::vector data(std::istream_iterator<int>(dataStream), {});
// And close the file
dataStream.close();
// Do any modification. Example flip bits for line 6 to 8
for (size_t line{ 6 }; data.size() > 8 and line < 8; ++line)
data[line] = 1 - data[line];
// Write all file to file
{
if (std::ofstream dataStream{ "fc3-4.txt" }; dataStream) {
// Write all data to file
std::copy(data.begin(), data.end(), std::ostream_iterator<int>(dataStream, "\n"));
}
else std::cerr << "\nError, Cannot open file for writing\n";
}
}
else std::cerr << "\nError, Cannot open file for reading\n";
}

Read specific information in a text file

As my title specifies,
I need to read information within a text file (C++).
I saw many example involving text file organized as list of numbers or strings, but in my case I need to extract the information within a file (example.txt) organized as follow:
// This is the begin of the text file:
Here_the_coordinates_are_going_to_be_listed
Start
x y z
0 0 0
1 0 0
1 1 0
0 1 0
End
And I would ideally read and store in "std::vector" the information contained between "Start" and "End" such that matrix is a N x 3 vector:
matrix[i][j] = 0 0 0
1 0 0
1 1 0
0 1 0
I gave a look at the tutorials and all I've got so far was:
std::array<std::array<int , 5>, 7> matrix;
std::ifstream file("../test/matrix.txt");
for (unsigned int i = 0; i < 7; i++)
{
for (unsigned int j = 0; j < 5; j++) {
file >> matrix[i][j];
}
which allows me to read a file where only numbers are written.
Thank you very much,
dARIO
go look here: http://www.cplusplus.com/doc/tutorial/files/ on how to read/write to files, then you can go through the file and look for the first relevant character (or last irelvant character, like the z in this case) and then just loop through all the relevant characters and store them in a 2 dimensional array (could be dynamic too if you do not know the length of your list)
EDIT:
So here is an example from that website of how to read a text file it is from the link above (which I updated, I'm very sorry about that) So basically the idea is as you see below, you open the file and then you just loop through every single line here (I think you can also use getchar for characters instead, which is probably better for you, but I am not too sure how excatly that works, you're just gonna have to mess around with that a bit, I'm sure you'll get it :) ) So here the line is just saved in a string and then printed out using cout, but you could manipulate the string further to find your data, I hope that helps! Feel free to ask again if I wasn't clear enough
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}

reading file and split the line in c++

I have the following code that read input from txt file as follow
Paris,Juli,5,3,6
Paris,John,24,2
Canberra,John,4,3
London,Mary,29,4,1,2
my code is to load the data into map then I want to print the map content to make sure that it has been inserted correctly, I check the vaue of m as it is used during splitting the line. However, during the execution I get this as continues 0s which means it is never enter the while loop. I have used this part of code before and it works. I could not find where I've made the mistake.
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include<map>
using namespace std;
struct info {
string Name;
int places;// i will use the binary value to identfy the visited places example 29 is 100101
// this means he visited three places (London,LA,Rome)
vector<int> times; // will represent the visiting time,e.g. 1,2,5 means london 1 time, LA
// twice and Rome five times
};
map<string,vector<info> > log;
map<string,vector<info> >::iterator i;
fstream out;
int main() {
out.open("log.txt", std::ios::in | std::ios::out | std::ios::app);
string line;
char* pt;
string temp[19];
// for each line in the file
while (!out.eof())
{
getline(out,line);//read line from the file
pt=strtok(&line[0],"," );//split the line
int m=0;
while (pt != NULL)
{
temp[m++] = pt; // save the line info to the array
cout<<m<<" ";
pt = strtok (NULL, ",");
}
cout<<m<<" "; // during the execution I get this as continues 0s which means it is never enter the while loop
info tmp;
// read the other data
tmp.Name=temp[1];
tmp.places=atoi(temp[2].c_str());
for ( int i=3;i<=m;i++)
{
tmp.times.push_back(atoi(temp[i].c_str()));
}
// create a new object
log[temp[0]].push_back(tmp);
}
vector<int>::iterator j;
for(i=log.begin();i!=log.end();i++) {
cout<< "From "<< i->first<<" city people who travels: "<<endl;
for (size_t tt = 0; tt < (i->second).size(); tt++) {
cout<< (i->second[tt]).Name<< " went to distnations "<< (i->second)[tt].places<<" \nwith the folloing number of visiting time ";
for (j=((i->second[tt]).times).begin();j!= ((i->second[tt]).times).end();j++)
cout<<*j<<" ";
}
}
system("PAUSE");
return 0;
}
This is an error
// for each line in the file
while (!out.eof())
{
getline(out,line);//read line from the file
should be
// for each line in the file
while (getline(out,line))
{
I find it frankly incredible how often this error is repeated. eof does not do what you think it does. It tests if the last read failed because of end of file. You are using it to try and predict whether the next read will fail. It simply doesn't work like that.
This line is an error
pt=strtok(&line[0],"," );//split the line
strtok works on C strings, there's no guarantee it will work on std::string.
But neither of these are likely to be your real error. I would suggest opening the file with ios::in only. After all you only want to read from it.
Your fstream should not open in app mode. That will seek the file to the end of file. Delete std::ios::app from it.
You can't tokenize an std::string using strtok. Use getline instead:
std::string str("some,comma,separated,data");
std::string token;
while (getline(str, token, ',')) {
cout << "Token: " << token << end;
}
At each iteration, token contains the next parsed token from str.
This is wrong temp[m++] = pt; // save the line info to the array
Switch to something like this, instead of "temp"
std::vector<std::string> vTemp;
pt=strtok(&line[0],"," );//split the line
while (pt != NULL)
{
vTemp.push_back(pt); // save the line info to the array
pt = strtok (NULL, ",");
}
Also consider using something like this to do the split.
std::vector<std::string> SplitString(const std::string &strInput, char cDelimiter)
{
std::vector<std::string> vRetValue;
std::stringstream ss(strInput);
string strItem;
while(std::getline(ss, strItem, cDelimiter))
{
// Skip Empty
if(strItem.size()==0)
continue;
vRetValue.push_back(strItem);
}
return vRetValue;
}
#halfelf really great solution for my simple error, it works but the problem is now when I print the data I got this
From Paris city people who travels:
Juli went to distnations 5
with the folloing number of visiting time 3 6 0
John went to distnations 24
with the folloing number of visiting time 2 6
From Canberra city people who travels:
Johnwent to distnations 4
with the folloing number of visiting time 3 6
From London city people who travels:
Mary went to distnations 29
with the folloing number of visiting time 4 1 2 0
This is not correct as 6 is added to John from Canberra and Paris and 0 is added to Juli and Mary.
any idea of where I get it wrong ,, its about the times vector , its seems that I need to reset the value for each line or clear the content after the insertion. what about the extra 0?

C++ Fstream to replace specific line?

okay i'm stumped on how to do this. I managed to get to the line I want to replace but i don't know how to replace it.
say a file called file.txt containts this:
1
2
3
4
5
and I want to replace line 3 so that it says 4 instead of 3. How can I do this?
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
fstream file;
string line;
int main(){
file.open("file.txt");
for(int i=0;i<2;i++){
getline(file,line);
}
getline(file,line);
//how can i replace?
}
Assuming you have opened a file in read/write mode you can switch between reading and writing by seeking, including seeking to the current position. Note, however, that written characters overwrite the existing characters, i.e., the don't insert new characters. For example, this could look like this:
std::string line;
while (std::getline(file, line) && line != end) {
}
file. seekp(-std::ios::off_type(line.size()) - 1, std::ios_base::cur);
file << 'x';
Even if you are at the right location seeking is needed to put the stream into an unbound state. Trying to switch between reading and writing without seeking causes undefined behavior.
The usual approach is to read from one file while writing to another. That way you can replace whatever you want, without having to worry about whether it's the same size as the data it's replacing.