Replacing a substring with a string

I need to replace a substring with a string.

This is what it says to do:Command line tool: You are to develop a program that will change all occurances of one string in a file to a different one. Your program will read from the standard input and write to the standard output.

For example, if your program is called prog1 here is an example of calling it:
 
 bin01010% ./prog1 “input” “output” < file1.txt > file2.txt 

The result of executing this command is that file2.txt is a copy of file1.txt, with every instance of the string input replaced by output.Your program will be graded on style (readability, by the grader) and correctness.

Details
To simplify grading, your program should read all input from standard input(cin) and write all output to standard output (cout). Do not prompt the user or produce any additional output. To have a file act as though it was typed into the keyboard, you can run your program like the following:
bin01010% ./prog1 “yellow duck” “black pig” < file1.txt > file2.txt
The “<” symbol is for file redirection, which means that when your program executes a cin instruction, it will read from file1.txt rather than the keyboard. The “>” symbol is for file redirection, which means that when your program executes a cout instruction, it will write to file2.txt rather than the screen.

Here is the code i have now:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include iostream;
#include stringstream;
#include cstdlib;

using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::stringstream;

void replace(string & content);

int main(int argc, char* argv[])
{
	if(argc == 3)
        {
	    stringstream ss;
	    ss << cin.rdbuf();
	    string contents = ss.str();	
	    cout << contents << endl;
	    string goReplace;
	    string ReplaceWith;
	

	    replace(contents, goReplace, ReplaceWith);
        }
    else
    {
	   cout << "Incorrect Arguments Passed."	
    }
	return 0;
}
void replace(string & contents, string & goReplace, string &ReplaceWith){

}
 
#includes have basic syntax errors.

the first thing to do here is to learn to read the output of your compiler and fix the errors. Its missing the angle brackets <iostream> is what you needed.

next up, while harmless HERE, extra ; can drive you nuts later on.
#include <iostream> //no ; here.

if you ever do this on a compound statement (if, loops, etc) you will have a mess:
if(x ==3); //if x is 3, do nothing
oops(); //this happens every single time, no matter what x is, its not IN the condition, the condition controls the 'do nothing' empty ; statement.

stringstream is <sstream> …

you are using replace incorrectly...

take a crack at getting it to compile, by reading the error messages. The way I do it is to fix the first error it lists, and then compile again, as some errors cause fake error messages after so its easier to address them one by one in a small program, and talking about hours long compiles for big programs isn't important today.

if you get stuck we can help, but its better if you reinforce what you should have learned so far by fixing it yourself or at least trying to. And its a good try … clearly you did this yourself, which is +++ points these days...
Last edited on
Okay I have an updated version but get this error:

In file included from proj1.cpp:4:0:
replace.h:11:26: error: expected ‘)’ before ‘content’
void replace(std::string content, std::string toReplace, std::string replaceWith);
^~~~~~~
proj1.cpp:33:21: error: expected ‘)’ before ‘contents’
void replace(string contents, string toReplace, string replaceWith)
^~~~~~~~
replace.h:11:26: error: expected ‘)’ before ‘content’
void replace(std::string content, std::string toReplace, std::string replaceWith);
^~~~~~~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
my main:
#include <iostream>
#include <sstream>
#include <string>
#include "replace.h"

using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::stringstream;

int main(int argc, char* argv[])
{
	if(argc == 3)
        {
	    stringstream ss;
	    ss << cin.rdbuf();
	    string contents = ss.str();	
	    cout << contents << endl;

	    string toReplace = argv[2];
	    string replaceWith = argv[2];
	

	    replace(contents, toReplace, replaceWith);
        }
    else
    {
	   cout << "Incorrect Arguments Passed." <<endl;	
    }
	return 0;
}
void replace(string contents, string toReplace, string replaceWith)
{

	loc--;
	cout << content[loc+1] << endl;

	std::size_t loc;

	while(loc = contents.find((" " + toReplace), 0) != string::npos)
	{
	    contents.replace(loc+1, toReplace.length(), replaceWith);
	}
}

my header file

#ifndef replace
#define replace

void replace(std::string content, std::string toReplace, std::string replaceWith);

#endif

ok, couple of things.
replace is a standard string function, so you may have that problem I said where you named something after an existing item. Might rename it to Replace or something.

See if that is what is causing it.


loc does not appear to exist where you use it.

loc--; //does not exist.
cout << content[loc+1] << endl;

std::size_t loc; //now it does, this creates it. but compilers don't read backwards.



are you allowed to use the built in replace? Nevermind, I see that you did.

you are making this way, way too hard.

you can do this in about 10 lines in main.
loop to read a line
check the line for the replace string in a loop, and every time you find it, replace it with a call to replace
cout the modified string
until you can't read any more lines.

that is all you need to do. no extra function, no header file, etc.

I don't like to do this, but its a small, simple program, and a couple of the tricks are not clear to a beginner. I think it does what you need. You can test and debug it if not, its close ;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

int main(int argc, char* argv[])
{
	unsigned int i; //or size_t, if you like. Im a bit sloppy at times. 
	string s;
    string av1 = argv[1]; //lets convert the args to strings just to be clean
    string av2 = argv[2];  			
	while(	std::getline (std::cin,s)) //this WILL stop reading on the 
//magic end of file marker on a redirected file to the input stream. 
    {
	do
	{
	  i = s.find(av1);
	  if(i != string::npos)
      s.replace(i,av2.length()-1,av2); //you can use iterators here.  I hate iterators.    	  
	} while (i != string::npos); 
    cout << s << endl;
	}  
	return 0;
}

Last edited on
WOW i`m overthinking this way too much. Also I am required to have a .h file
well, you can clean it up by moving the thing to a function and having a header for that then.
Agreed. Now I just have to learn how to make a makefile for it!
SEP field. Im outta here!

If you use it, do make sure you understand it very well. Its not rocket science, but you need to be able to re-create that from scratch level of understanding, or this won't be anything but me doing it for you. If you can re-create it, you will think this way / be able to build off it in the future, and will have learned something.
Last edited on
Topic archived. No new replies allowed.