Remove/Replace line in file

I've been looking at sites for this and can't find a way to get it to work correctly. I'm trying to loop through my file to fine a line that matches a criteria and replace that line with another. If this isn't doable, I also thought about looping through the file, getting all the data into an vector or something, searching the vector for the criteria, removing it from the vector and rewriting the file.

Any ideas? I'm just looking for someone to lead me in the right direction.

Pseudo code:
1
2
3
4
5
6
1. start of loop
2. read a line
3. check the string to see if it contains the search word
4. if yes then write/replace the new line to output file and delete the original
5. if no then just write the line to output file
6. end of loop


I'm hung up on lines 3. I don't know how to search a line, only a word that is separated via space. I think I can figure out the rest but if any of you have some good knowledge of some pitfalls I might encounter I'd very much appreciate the heads up :)
You can't *easily* replace lines in files, you need to either do as you say and read the file in, change it and overwrite it, or copy the data from one file to another editing it on the way.
Last edited on
The idea with vectors sounds like a good one.
im new to C++ so sorry if this doesnt help

what bout reading the line into a string( lets say temp), then checking temp with the criteria. if true then replace temp with criteria. if false, read next line into temp and do the loop over... Hope that helps
SacredFootballLB wrote:
I'm hung up on lines 3. I don't know how to search a line, only a word that is separated via space.


You can search a string for a word like this:

1
2
3
4
5
6
7
std::string str;

if(str.find("word") != std::string::npos)
{
    // .. replace string
    str = "whatever...";
}
I take it you're familiar with the getline function? You can use it to parse out one line at a time from the file (as a string) as do the above search that Galik suggested. This will save you from having to store the entire file in a vector.
@sighter

That won't really work since I have 2 words on a single line and the second word can be across multiple lines. If I have Hardware or something on line 2 on multiple lines, I don't want it to replace all Hardwares ;)

@Zero One
Wow, major brain fart on my part. getline() was escaping my mind for some reason. I'll just do a loop through the end of the file and get each line. Storing the data in a vector could become resource inefficient if the file gets large.

I'll post my code as soon as I can. I forgot my flash drive with the code at home >.<
You can have two files open at the same time, writing to one and reading from the other. On the other hand, you can open a file in read/write mode. If that doesn't work or is infeasible in terms of memory usage, it is possible to open a file in write append mode.

That won't really work since I have 2 words on a single line and the second word can be across multiple lines. If I have Hardware or something on line 2 on multiple lines, I don't want it to replace all Hardwares ;)
What do you mean by this?
@smilodon
I knew I'd probably get asked that. I'll show what the file could look like. The example shows names and age.

FILE_NAME
---------------------------------
Heather 21
Devin 22
Wes 22
Nick 21
Brad 20

The second column can be found on multiple lines seen in the above example. I wouldn't want to search the file for "21" and replace it with 22 because not everyone would turn 22 at the same time. I'll need to search for "Heather" and replace the 21 with 22 when her birthday arrives.
I cannot get the getline() to work correctly. Here's my current code:

1
2
3
4
5
6
7
string tmp = name + " " + age;
string findMe "Heather 21";
while(!fc.getInFile().eof()) {
	fc.getInFile().getline;
	if (findMe.find(tmp) != std::string::npos) {
		cout << "MATCH!" << endl;
	}


fc is using the FileController class
1
2
3
4
5
6
7
8
9
10
11
ifstream &FileController::getInFile() {
	if (!inFile) {
		ofstream saveNew(MY_FILE_NAME_);
		saveNew.close();
	} 

	if(!inFile.is_open()) {
		inFile.open(MY_FILE_NAME_);
	}
        return inFile;
}
The following statement
if(a && b)
only gets executed if statements a and b are true.
@sighter

That won't really work since I have 2 words on a single line and the second word can be across multiple lines. If I have Hardware or something on line 2 on multiple lines, I don't want it to replace all Hardwares ;)


oh my bad, i thought u wanted to search the whole line and replace it. I would do what Zero one said, seems the most simple way of doing it to me.

@smilodon

Yes that statement will only execute if both a and b are true but I don't use that anywhere in my code...
Galik, you are awesome. That's exactly what I needed!

Here's the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
vector<string> data;
int prevScore = getPersonalHigh(userName);
stringstream ss;
ss << prevScore;
string tmp = userName + " " +ss.str();
string line;
while (getline(fc.getInFile(), line)) {
	if (line.find(tmp) == std::string::npos || prevScore == 0) {
		data.push_back(tmp);
	} else {
		data.push_back(line);
	}
}

if (fc.getInFile().is_open()) {
		fc.getInFile().close();
	}
ofstream myFile("HighScores.txt");
myFile.open("HighScores.txt", ios::app);
int looper;
for (looper = 0; looper < (int) data.size(); looper++) {
	myFile << data[looper] << endl;
}
myFile.close();


The only problem I'm having now is rewriting the data back to the file using a vector. What am I missing?
What you have there looks like it should work. What happens?
I found the problem. Noob moment.

1
2
ofstream myFile("HighScores.txt");
myFile.open("HighScores.txt", ios::app);


Thanks everyone for you're help! You're all an amazing help :D
Last edited on
Topic archived. No new replies allowed.