String function in the C++ program.

Urgent for DEADLINE ._.
I am writing a program for assignment that reads an input from an existing txt file and after some modification, it will be exported to a newly created txt file.

The program actually requires me to change text like "what the foundation", "water, take, food" or phrase starting with W, T and F to "WTF" directly, but not phrases like "what you take for". It will read from an input file named "input.txt" with initialized text inside. After processing the program, the input will be changed depends on the situation, and output to a new txt named "output.txt".

After editing the program, I cannot get the expected output from the file...I can generate the original input in the output file, but the WTF isn't working to replace words like "What the foundation". The debugger shows only a message of "Process returned 0". I wonder is there a problem regarding the string.replace function, since I am also not sure on how to use it.

e.g. Input : Hello ! What the foundation will do is...
Expected Output: Hello ! WTF will do is...
Output now: Hello! What the foundation will do is...

Input: Hello! What a talented foundation will do is...
Output: Hello ! What a talented foundation will do is...

Below is the program attached. I am still new to programming. Thanks in advance if anyone can offer help to me! :D

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

bool correctorder (int b1, int c1, int d1)
{
    if (( b1 < c1 ) && ( c1 < d1 ))
        return 1;
    else
        return 0;
}

bool consecutive_a (int space_a)
{
    if ( space_a == 1 )
        return 1;
    else
        return 0;
}

bool consecutive_b (int space_b)
{
    if ( space_b == 1 )
        return 1;
    else
        return 0;
}

int main()
{
    ifstream datainput;
    ofstream dataoutput;
    string input ;
    int a, b, c, d, e, f;
    int spacecount_a = 0;
    int spacecount_b = 0;
    string string1 = "WTF";

    datainput.open ("input.txt");

    if (datainput.fail())
    {
        cout << "Error in file opening" << endl;
    }
    else
    {
        datainput >> noskipws;
        getline(datainput, input);

        datainput.close();

        dataoutput.open("output.txt");

        for ( a = 0 ; a < 100 ; a++ )
        {
            switch(input[a])
            {
            case ',':
            case '.':
            case '?':
            case '!':
            case ' ':
                switch(input[a+1])
                {
                case 'w':
                case 'W':
                    b = a;
                    break;
                case 't':
                case 'T':
                    c = a;
                    break;
                case 'f':
                case 'F':
                    d = a;
                    break;
                default:
                    break;
                }
                break;
            default:
                break;
            }
        }

        for ( e = b ; e <= c ; e++ )
        {
            if ( (input [e] == ',' )|| (input [e] == '.') || (input [e] == '?') || (input [e] == '!') || (input [e] == ' ') )
            {
                spacecount_a ++ ;
            }
        }

        for ( f = c ; f <= d ; f++ )
        {
            if ( (input [f] == ',') || (input [f] == '.') || (input [f] == '?') || (input [f] == '!') || (input [f] == ' ') )
            {
                spacecount_b ++ ;
            }
        }

        if ( (correctorder (b, c, d) == 1) && (consecutive_a (spacecount_a) == 1) && (consecutive_b (spacecount_b) == 1) )
        {
            input.replace( b, (d-b), string1 );
        }

        if (dataoutput.fail())
        {
            cout << "Error in file outputting" << endl;
        }
        else
        {
            dataoutput << input << endl;
            dataoutput.close();
        }
    }
}
Last edited on
I can't believe it compiles: it's the first time a see functions defined inside main()
=:-O

Anyway, please consider
1) taking your
- bool correctorder (string Input);
- bool consecutive_a (string Input);
- bool consecutive_b (string Input);
out from main() and invoke them properly.

2) using switch instead or really complex ifs.
For example:
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
for ( a = 0 ; a < 100 ; a++ )
{
    switch(input[a])
    {
    case ',': case '.': case '?':
    case '!': case ' ':
        switch(input[a+1])
        {
        case 'w': case 'W':
            b = a;
            break;
        case 't': case 'T':
            c = a;
            break;
        case 'f': case 'F':
            d = a;
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }
}


3) using the "code" tags to write your code inside the post (find the menu on the right)

4) explaining what your input file looks like (a short example?) and what your output file should look like.
I have taken out the functions from main program, and edited it in the first comment...Thanks for your help ! @Enoizat :)
Last edited on
Can anyone please help...T.T
C'mon, paulpaul,
please give us your new code, an example of your input file and a description of what the output file should look like.
We are not clairvoyants. Or, at least, I'm definitely not one.
I have edited the program again to become something like this...
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

bool correctorder (int b1, int c1, int d1)
{
    if (( b1 < c1 ) && ( c1 < d1 ))
        return 1;
    else
        return 0;
}

bool consecutive_a (int space_a)
{
    if ( space_a == 1 )
        return 1;
    else
        return 0;
}

bool consecutive_b (int space_b)
{
    if ( space_b == 1 )
        return 1;
    else
        return 0;
}

int main()
{
    ifstream datainput;
    ofstream dataoutput;
    string input ;
    int a, b, c, d, e, f, g;
    b = 0;
    c = 0;
    d = 0;
    g = d - b;
    int spacecount_a = 0;
    int spacecount_b = 0;
    string string1 = "WTF";

    datainput.open ("input.txt");

    if (datainput.fail())
    {
        cout << "Error in file opening" << endl;
    }
    else
    {
        datainput >> noskipws;
        getline(datainput, input);

        datainput.close();

        dataoutput.open("output.txt");

        for ( a = 0 ; a < 100 ; a++ )
        {
            switch(input[a])
            {
            case ',':
            case '.':
            case '?':
            case '!':
            case ' ':
                switch(input[a+1])
                {
                case 'w':
                case 'W':
                    b = a;
                    break;
                case 't':
                case 'T':
                    c = a;
                    break;
                case 'f':
                case 'F':
                    d = a;
                    break;
                default:
                    break;
                }
                break;
            default:
                break;
            }
        }

        for ( e = b ; e <= c ; e++ )
        {
            if ( (input [e] == ',' )|| (input [e] == '.') || (input [e] == '?') || (input [e] == '!') || (input [e] == ' ') )
            {
                spacecount_a ++ ;
            }
        }

        for ( f = c ; f <= d ; f++ )
        {
            if ( (input [f] == ',') || (input [f] == '.') || (input [f] == '?') || (input [f] == '!') || (input [f] == ' ') )
            {
                spacecount_b ++ ;
            }
        }

        if ( (correctorder (b, c, d) == 1) && (consecutive_a (spacecount_a) == 1) && (consecutive_b (spacecount_b) == 1) )
        {
            input.substr( b, g ) = string1;
        }

        if (dataoutput.fail())
        {
            cout << "Error in file outputting" << endl;
        }
        else
        {
            dataoutput << input << endl;
            dataoutput.close();
        }
    }
}


After editing the program, I cannot get the expected output from the file...I can generate the original input in the output file, but the WTF isn't working to replace words like "What the foundation". The debugger shows only a message of "Process returned 0". I wonder is there a problem regarding the string.replace function, since I am also not sure on how to use it.

e.g. Input : Hello ! What the foundation will do is...
Expected Output: Hello ! WTF will do is...
Output now: Hello! What the foundation will do is...

Input: Hello! What a talented foundation will do is...
Output: Hello ! What a talented foundation will do is...
If what you want is to replace all the occurrences of "what the foundation" (regardless if there are uppercase or not), you can do it with a code like the following.

Otherwise, I'm afraid you need to be more specific, because I'm not sure I understand what you want.

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

int main()
{
    std::ifstream infile("lorem_ipsum.txt");
    std::vector<std::string> text;
    std::string words;
    while(std::getline(infile, words)) {
        // std::getline skips newline., so we need to restore them;
        words += '\n';
        text.push_back(words);
    }
    infile.close();

    for(auto& line : text) {
        // copy "line" into another string, but all lowercase
        std::string tmpstr = line;
        for(char& onech : tmpstr) {
            onech = std::tolower(onech);
        }

        std::string::size_type pos = tmpstr.find("what the foundation");
        while(std::string::npos != pos) {
            // what is to be modified, of course, is the original
            line.replace(pos, 19, "WTF");
            tmpstr = line;
            for(char& onech : tmpstr) {
                onech = std::tolower(onech);
            }
            pos = tmpstr.find("what the foundation");
        }
    }

    std::ofstream outfile("WTFloremipsum");
    for(const auto w : text) {
        outfile << w;
    }
    outfile.close();

    return 0;
}


lorem_ipsum.txt:

Lorem ipsum dolor sit amet, cum et probo graeci, et pro soluta primis signiferumque. Eam at accumsan invidunt signiferumque, fierent volutpat nec at, error accusamus intellegebat nam at. What the foundation labores definiebas. Inani laudem cum at, te vero iriure appellantur qui.

Mazim errem what the foundation. No vis harum iracundia. Vidit aliquip at pro, malis dicam voluptatum qui ex. Probo lucilius ea his, vel prima theophrastus eu, duo ex alii constituam interpretaris.

Duo ut dicat assum percipit. Id cum unum malis signiferumque. Vivendum sapientem vituperata ius ei. Est amet animal definitiones te.

Mundi veniam pro id. Has id reque integre splendide. Id eam ornatus partiendo. Ex vis modo detraxit comprehensam, what the foundation constituam. Et sonet graece erroribus per, ut labores iracundia eum.

Menandri intellegebat consectetuer ne eam, pri ne possim debitis platonem. Te affert nostro definitionem pri. What the Fundation vix, qui inermis fierent ad. Adhuc nostrum vituperata quo eu, te eos magna clita omittantur, ad sea wisi omnes. Wisi movet corrumpit est an.

Sea ad ferri deterruisset conclusionemque, simul audire ad eum. Qui ubique democritum at, ea regione inimicus eum, suscipit appetere efficiendi ea sed. Ea clita consequat philosophia mea. Elit lorem qui at, at cum nobis malorum.


WTFloremipsum.txt:

Lorem ipsum dolor sit amet, cum et probo graeci, et pro soluta primis signiferumque. Eam at accumsan invidunt signiferumque, fierent volutpat nec at, error accusamus intellegebat nam at. WTF labores definiebas. Inani laudem cum at, te vero iriure appellantur qui.

Mazim errem WTF. No vis harum iracundia. Vidit aliquip at pro, malis dicam voluptatum qui ex. Probo lucilius ea his, vel prima theophrastus eu, duo ex alii constituam interpretaris.

Duo ut dicat assum percipit. Id cum unum malis signiferumque. Vivendum sapientem vituperata ius ei. Est amet animal definitiones te.

Mundi veniam pro id. Has id reque integre splendide. Id eam ornatus partiendo. Ex vis modo detraxit comprehensam, WTF constituam. Et sonet graece erroribus per, ut labores iracundia eum.

Menandri intellegebat consectetuer ne eam, pri ne possim debitis platonem. Te affert nostro definitionem pri. What the Fundation vix, qui inermis fierent ad. Adhuc nostrum vituperata quo eu, te eos magna clita omittantur, ad sea wisi omnes. Wisi movet corrumpit est an.

Sea ad ferri deterruisset conclusionemque, simul audire ad eum. Qui ubique democritum at, ea regione inimicus eum, suscipit appetere efficiendi ea sed. Ea clita consequat philosophia mea. Elit lorem qui at, at cum nobis malorum.


Sorry.
My program requires me to replace three consecutive words starting with W, T and F (both upper case and lower case) with "WTF" directly, so I may need a more general case to detect all the words starting with the three characters and showed that they are linked (or separated by '.' ',' '!' or '?'), such that WTF can be used to replace the three words. No spaces or punctuation marks will appear inside one word, but there may be multiple spaces or punctuation marks between two words.

Input like: Well! The food is not good! will also be changed to WTF is not good!

Sorry that I may not be clear in expressing what exactly the assignment required me to do...

Thanks for your help anyway :)
Last edited on
If you're allowed to use regex:

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
// http://ideone.com/G4HUVM
#include <iostream>
#include <regex>
#include <string>

int main() {

    std::vector<std::string> text = {
        "Hello ! What the foundation will do is...",
        "Hello! What a talented foundation will do is...",
        "water, take, food",
        "what you take for",
        "Well! The food is not good!"
    };

    auto wtf_ex = std::regex{R"(\b[wW]+[\w]*[\W]+[tT]+[\w]*[\W]+[fF]+[\w]*)"};


    for (const auto& unmodified : text) {
        auto modified = 
            std::regex_replace(unmodified, wtf_ex, "WTF");

        std::cout << "\n\nUnmodified: " << unmodified;
        std::cout << "\nModified:   " << modified;
    }
}


If not, a state machine seems like it might be in order.

Last edited on
Sorry that regex is not allowed...but thanks for your help :)

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

bool correctorder (int b1, int c1, int d1)
{
    if ( b1 < c1 && c1 < d1 )
        return 1;
    else
        return 0;
}

bool consecutive_a (int space_a)
{
    if ( space_a == 2 )
        return 1;
    else
        return 0;
}

bool consecutive_b (int space_b)
{
    if ( space_b == 2 )
        return 1;
    else
        return 0;
}

int main()
{
    ifstream datainput;
    ofstream dataoutput;
    string input ;
    int a, b, c, d, e, f, g, h;
    b = 0;
    c = 0;
    d = 0;
    g = 0;
    int spacecount_a = 0;
    int spacecount_b = 0;
    string string1 = "WTF";

    datainput.open ("input.txt");

    if (datainput.fail())
    {
        cout << "Error in file opening" << endl;
    }
    else
    {
        datainput >> noskipws;
        getline(datainput, input);

        datainput.close();

        dataoutput.open("output.txt");

        for ( a = 0 ; a < 100 ; a++ )
        {
            if ( (input [a] == ',' && input [a + 1] == 'W') ||
                    (input [a] == ',' && input [a + 1] == 'w') ||
                    (input [a] == '.' && input [a + 1] == 'W') ||
                    (input [a] == '.' && input [a + 1] == 'w') ||
                    (input [a] == '?' && input [a + 1] == 'W') ||
                    (input [a] == '?' && input [a + 1] == 'w') ||
                    (input [a] == '!' && input [a + 1] == 'W') ||
                    (input [a] == '!' && input [a + 1] == 'w') ||
                    (input [a] == ' ' && input [a + 1] == 'W') ||
                    (input [a] == ' ' && input [a + 1] == 'w')
               )
                b = a;

            if ( (input [a] == ',' && input [a + 1] == 'T') ||
                    (input [a] == ',' && input [a + 1] == 't') ||
                    (input [a] == '.' && input [a + 1] == 'T') ||
                    (input [a] == '.' && input [a + 1] == 't') ||
                    (input [a] == '?' && input [a + 1] == 'T') ||
                    (input [a] == '?' && input [a + 1] == 't') ||
                    (input [a] == '!' && input [a + 1] == 'T') ||
                    (input [a] == '!' && input [a + 1] == 't') ||
                    (input [a] == ' ' && input [a + 1] == 'T') ||
                    (input [a] == ' ' && input [a + 1] == 't')
               )
                c = a;

            if ( (input [a] == ',' && input [a + 1] == 'F') ||
                    (input [a] == ',' && input [a + 1] == 'f') ||
                    (input [a] == '.' && input [a + 1] == 'F') ||
                    (input [a] == '.' && input [a + 1] == 'f') ||
                    (input [a] == '?' && input [a + 1] == 'F') ||
                    (input [a] == '?' && input [a + 1] == 'f') ||
                    (input [a] == '!' && input [a + 1] == 'F') ||
                    (input [a] == '!' && input [a + 1] == 'f') ||
                    (input [a] == ' ' && input [a + 1] == 'F') ||
                    (input [a] == ' ' && input [a + 1] == 'f')
               )
                d = a;
                
            
        }

        for ( g = (d + 1) ; g < 100 ; g++ )
        {
            if ( (input [g] == ',' )|| (input [g] == '.') || (input [g] == '?') || (input [g] == '!') || (input [g] == ' ') )
            {
                break;
            }
        }

        for ( e = b ; e <= c ; e++ )
        {
            if ( (input [e] == ',' )|| (input [e] == '.') || (input [e] == '?') || (input [e] == '!') || (input [e] == ' ') )
            {
                spacecount_a ++ ;
            }
        }

        for ( f = c ; f <= d ; f++ )
        {
            if ( (input [f] == ',') || (input [f] == '.') || (input [f] == '?') || (input [f] == '!') || (input [f] == ' ') )
            {
                spacecount_b ++ ;
            }
        }

        if (dataoutput.fail())
        {
            cout << "Error in file outputting" << endl;
        }
        else
        {
            if ((correctorder (b, c, d) == 1) && (consecutive_a (spacecount_a) == 1) && (consecutive_b (spacecount_b) == 1) )
            {
                dataoutput << input.substr ( 0, b ) << string1 << input.substr (g) << endl;
            }
            else
            {
                dataoutput << input << endl;
            }

            dataoutput.close();
        }
   }
}


this is the code I have now... but only one set of words starting with WTF can be detected...Whenever I have more than one set of words starting with WTF, the program will just change one of them...
Last edited on
Perhaps, this might help. (Replaces all two-word sequences beginning with the letters W (or w) and T (or T) in that order with the token "WT")
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
#include <cctype>
#include <iostream>
#include <string>
#include <vector>

// returns the index of the first letter in the next word, given a position in the string
std::size_t next_word(const std::string& text, std::size_t pos) {    
    // move to the end of the current word, if any.
    while (pos != text.size() && std::isalnum(text[pos]))
        ++pos;

    // skip over any non-word characters between words
    while (pos != text.size() && !std::isalnum(text[pos]))
        ++pos;

    return pos;
}

// returns the length of a word, given the position of that word in the string
std::size_t word_length(const std::string& text, std::size_t pos) {
    std::size_t end_pos = pos;
    while (end_pos != text.size() && std::isalnum(text[end_pos])) 
        ++end_pos;

    return end_pos - pos;
}

void replace(std::string& text) {
    std::size_t working_pos = 0;

    while (working_pos != text.size()) {
        std::size_t next = next_word(text, working_pos);

        if (std::tolower(text[working_pos]) == 'w' ) {
            if (next != text.size() && std::tolower(text[next]) == 't')
            {
                text.replace(working_pos, next - working_pos + word_length(text, next), "WT");
                next = next_word(text, working_pos);
            }
        }

        working_pos = next;
    }
}

int main() {

    std::vector<std::string> text = {
        "Hello ! What the foundation will do is...",
        "Hello! What a talented foundation will do is...",
        "water, take, food",
        "what you take for",
        "Well! The food is not good!",
        "Well, that is not good at all.  We tie where time will tell."
    };

    for (const auto& unmodified : text) {
        auto modified = unmodified;
        replace(modified);
 
        std::cout << "\n\nUnmodified: " << unmodified;
        std::cout << "\nModified:   " << modified;
    }
}


Last edited on
Here's a slightly different approach to the same problem (untested code):
EDIT: Well, different from the earlier code; this approach is the same as the one by cire.

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
67
68
69
70
71
#include <string>

bool is_word_separator( char c )
{
    static const std::string separators = " \t\n.,!?" ;
    return separators.find(c) != std::string::npos ;
}

bool is_word_begin( std::string str, std::size_t pos )
{
    if( str.empty() ) return false ;
    if( pos == 0 ) return !is_word_separator( str[0] ) ;
    return !is_word_separator( str[pos] ) && is_word_separator( str[pos-1] ) ;
}

// return position of end of word (end == one past the last character)
std::size_t word_end( std::string str, std::size_t pos )
{
    while( pos < str.size() && !is_word_separator( str[pos] ) ) ++pos ;
    return pos ;
}

std::size_t word_size( std::string str, std::size_t pos )
{ return is_word_begin( str, pos) ? word_end(str,pos) - pos : 0 ; }

std::size_t next_word_begin( std::string str, std::size_t pos )
{
    ++pos ;
    while( pos < str.size() && !is_word_begin(str,pos) ) ++pos ;
    return pos ;
}

std::size_t first_word_begin( std::string str )
{
    std::size_t pos = 0 ;
    while( pos < str.size() && !is_word_begin(str,pos) ) ++pos ;
    return pos ;
}

// return true if the three words from pos start with w,t,f respectively
bool is_wtf( std::string str, std::size_t pos ) // does a look ahead
{
    if( is_word_begin(str,pos) && std::tolower( str[pos] ) == 'w' )
    {
        pos = next_word_begin(str,pos) ;
        if( pos < str.size() && std::tolower( str[pos] ) == 't' )
        {
            pos = next_word_begin(str,pos) ;
            return pos < str.size() && std::tolower( str[pos] ) == 'f' ;
        }
    }

    return false ;
}

// invariant: is_wtf(str,pos)
std::string replace_wtf_at( std::string str, std::size_t pos )
{
    auto pt = next_word_begin(str,pos) ;
    auto pf = next_word_begin( str, pt ) ;
    auto cnt = pf - pos + word_size(str,pf) ;
    return str.replace( pos, cnt, "WTF" ) ;
}

std::string replace_wtf( std::string str )
{
    for( auto p = first_word_begin(str) ; p < str.size() ; p = next_word_begin(str,p) )
        if( is_wtf(str,p) ) str = replace_wtf_at(str,p) ;

    return str ;
}

http://coliru.stacked-crooked.com/a/9700dc701d703bc5
Last edited on
Thanks for all your help :D
Topic archived. No new replies allowed.