Find and replace characters in file

I'm writing a program which finds and replaces characters in an input file, and print the file content in an output file. I'm able to write the program using string method. But requirement is to use character method. Except for the 4 input parameters I do not know how to modify the rest codes using character and its methods. Could anyone please help? Thank you.

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
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
    string inFile = string(argv[1]);      //input file name
    string outFile = string(argv[2]);     //output file name
    string chrToFind = string(argv[3]);   //characters to find
    string chrToReplace = string(argv[4]);//characters to replace

    //modify above 4 parameters to below
    //const char *const inFile = argv[1];
    //const char *const outFile = argv[2];
    //char *chrToFind = argv[3];
    //char *chrToReplace = argv[4];
  
    ifstream inputFileStream(inFile, ifstream::in);
    ofstream outputFileStream(outFile);

    string line; //Please advise how to revise code starting from here
                 //to use character and character method. Thank you.
    while (getline(inputFileStream, line))
    {
        size_t substringPos;
        while ((substringPos = line.find(chrToFind)) != string::npos)
        {
            line.replace(substringPos, chrToFind.size(), chrToReplace);
        }
        outputFileStream << line << '\n';
    }
    outputFileStream.close();
    inputFileStream.close();

    return 0;
}
Last edited on
Instead of getline(stream, string), use cin.getline (char* s, streamsize n ); where s is a buffer and n is the length of that buffer (null terminator will be written for you).

e.g.
1
2
char line[1000];
cin.getline(line, 1000);


To find a substring, research strstr.
To replace characters, probably just write the logic yourself by iterating through each character and shifting them.

Be sure to #include <cstring> when using functions meant for c-style strings.
Last edited on
Hello Simon90,

First off how do you know if you have the right command line number of arguments?

Then how do you know if the input file stream is open and ready to use?

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
int main(int argc, char *argv[])
{
    //string inFile = string(argv[1]);      //input file name
    //string outFile = string(argv[2]);     //output file name
    //string chrToFind = string(argv[3]);   //characters to find
    //string chrToReplace = string(argv[4]);//characters to replace

    if (argc != 5)
    {
        std::cerr <<
            "\n     Inproper arguements on command line!\n"
            "\n Should be input file name output file name character to find character to replace.\n";

        return 1;
    }

    //modify above 4 parameters to below
    const char *const inFileName = argv[1];
    const char *const outFileName = argv[2];
    char *chrToFind = argv[3];
    char *chrToReplace = argv[4];

    ifstream inFile(inFileName);

    if (!inFile)
    {
        std::cerr << "\n     File \"" << inFileName << "\" did not open!\n";

        return 2;
    }

    ofstream outFile(outFileName);

It would be a good idea to check "argc" before you start using "argv[1] - [4]".

When opening an input file it prety must a must to check that the file is open and usable.

The way you are using the "ofstream" it will create the file, in the current working directory, if it does not exist. If you use a path you will need to check it as I did for the input.

An alternative is: while (inFile.get(ch)). Then inside the loop just check the character read against "charToFind" and output the replacement or the character (ch) read.

One tip when you use "charToFind" in the if statement do not forget to de-reference it.

Andy

EDIT: typo
Last edited on
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
57
58
59
60
61
62
63
64
65
66
#include <fstream>
#include <iostream>

int main(int argc, char *argv[])
{
    int count;
    std::cout << "This program was called with " << argv[0] << '\n';
    
    if (argc > 1)
    {
        for (count = 1; count < argc; count++)
        {
            std::cout << "argv[" << count << "] " << argv[count] << '\n';
        }
    }
    else
    {
        std::cout << "The command had no other arguments.\n";
        return -99;
    }
    
    char change_from = argv[1][0];
    char change_to = argv[2][0];
    
    std::cout << "Change from: " << change_from << '\n';
    std::cout << "Change   to: " << change_to << '\n';

    // SOURCE FILE
    std::ifstream file_from;
    file_from.open("ch_read_from.txt");
    
    if (file_from.fail())
    {
        std::cout << "Error opening file: ";
        exit(1);
    }
    
    // DESTINATION FILE
    std::ofstream file_to;
    file_to.open("ch_write_to.txt");
    
    if (file_to.fail())
    {
        std::cout << "Error opening file: ";
        exit(2);
    }
    
    // PROCESS CHARACTER AT A TIME
    char ch_read;
    while (file_from.get(ch_read))
    {
        if(ch_read == change_from)
        {
            file_to << change_to;
        }
        else
        {
            file_to << ch_read;
        }
    }
    
    std::cout << "Done\n";
    
    return 0;
}



Mac terminal input first line, then output ..

 ./General e U
This program was called with ./General
argv[1] e
argv[2] U
Change from: e
Change   to: U
Done


Input file:
The Constitution of the People's Republic of China is nominally the supreme
law of the People's Republic of China. It was adopted by the 5th National
People's Congress on December 4, 1982, with further revisions about every
five years.

It is the fourth constitution in the country's history,
superseding the 1954 constitution, the 1975 constitution, and the 1978
constitution.


Output file:
ThG Constitution of thG PGoplG's RGpublic of China is nominally thG suprGmG
law of thG PGoplG's RGpublic of China. It was adoptGd by thG 5th National
PGoplG's CongrGss on DGcGmbGr 4, 1982, with furthGr rGvisions about GvGry
fivG yGars.

It is thG fourth constitution in thG country's history,
supGrsGding thG 1954 constitution, thG 1975 constitution, and thG 1978
constitution.


PS The first few lines are not the usual error/man page checking - this was chosen just as an expedient.
Last edited on
againtry's baby code always makes me laugh!
What a loser.
@Simon90

BTW General has no significance other than being a project name from Xcode equivalent to whatever .exe file or similar/whatever with your OS.

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
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

int main( int argc, char *argv[] )
{
    const int MAXLINE = 1000;

    ifstream in ( argv[1] );
    ofstream out( argv[2] );
    char *strToFind    = argv[3];   int findLength = strlen( strToFind );
    char *strToReplace = argv[4];

    char line[MAXLINE];
    while ( in.getline( line, MAXLINE ) )
    {
        char *c = &line[0];
        while ( char *d = strstr( c, strToFind ) )
        {
           *d = '\0';
           out << c << strToReplace;
           c = d + findLength;
        }
        out << c << '\n';
    }
}

PS The first few lines are not the usual error/man page checking - this was chosen just as an expedient.
All fixed.

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
#include <fstream>
#include <iostream>

int main(int argc, char *argv[])
{
    if (argc != 5)
    {
        std::cout
        << "USAGE: prog fs fd from to\n"
        << " prog - program name\n"
        << "   fs - source file\n"
        << "   fd - destination file\n"
        << " from - single character to be change\n"
        << "   to - single character substitute\n"
        << '\n'
        << "Example: ./replace ch_s.txt ch_d.txt e X\n";
        
        exit(1);
    }
    
    std::cout
    << "Change from: " << argv[3][0] <<  " to: " << argv[4][0] << '\n';

    // SOURCE FILE
    std::ifstream file_from;
    file_from.open(argv[1]);
    if (!file_from.is_open() )
    {
        std::cout << "Error opening source file: ";
        exit(2);
    }
    
    // DESTINATION FILE
    std::ofstream file_to;
    file_to.open(argv[2]);
    
    // PROCESS CHARACTER AT A TIME
    char ch_read;
    while ( file_from.get(ch_read) )
    {
        if(ch_read == argv[3][0])
        {
            file_to << argv[4][0];
        }
        else
        {
            file_to << ch_read;
        }
    }
    
    std::cout << "Done\n";
    
    return 0;
}
Hello Simon90,

In your first post you refer to

But requirement is to use character method.



It is a little late, but now is a good time to post the full description of what the program should do, so that everyone will know what should be done.

Andy
I got it. Thanks all. Do appreciate you guys' help!
Topic archived. No new replies allowed.