Break string into seperate words and translate

I'm working on a homework assignment that translates English to Pig Latin, what I have so far gets the sentence but doesn't separate out the individual words and translate them. Instead from an input of "Meet me at the dock." I get "eet me at the dock.M-way" A co-worker of mine suggested using recursion to break the sentence into it individual words and then translate them but I can't figure out how to do that. The breakString function is what I've come up with so far from his suggestions, but I can't get it to break the words apart when it find whitespace.

Thanks in advance for any 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
#include <iostream>
#include <string>

using namespace std;

bool isVowel(char ch);
string rotate(string pStr);
string pigLatinString(string pStr);
string breakString(string pStr);

int main()
{
    string pStr;
    
    cout << "Enter a string: ";
    cout << endl;
    
    getline(cin, pStr);
    cout << endl;

    cout << "The pig Latin form of " << pStr << " is: "
         << breakString(pStr) << endl;
         //<< pigLatinString(str) << endl;

    cout << "Press ENTER to continue... ";
    cin.sync();
    cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

    return 0;
}

bool isVowel(char ch)
{
    switch (ch)
    {
    case 'A': 
    case 'E': 
    case 'I': 
    case 'O': 
    case 'U': 
    case 'Y':
    case 'a': 
    case 'e': 
    case 'i': 
    case 'o': 
    case 'u': 
    case 'y': 
        return true;
    default: 
        return false;
    }
}

string rotate(string pStr)
{
    string::size_type len = pStr.length();

    string rStr;

    rStr = pStr.substr(1, len - 1) + pStr[0];

    return rStr;
}


string breakString(string pStr)
{
    string rStr1;
    string rStr2;
    string rStr;

    rStr1 = rStr;
    rStr2 = (pStr - rStr);

    // remove leading space from rStr2;

    if (rStr2 = "")
        return pigLatinString(rStr1);
    else
        return pigLatinString(rStr1) + " " + breakString(rStr2);

}

string pigLatinString(string pStr)
{
    string::size_type len;

    bool foundVowel;
	
    string::size_type counter;

    if (isVowel(pStr[0]))
        pStr = pStr + "-way";	
    else
    {
        pStr = pStr + '-';
        pStr = rotate(pStr);

        len = pStr.length();
        foundVowel = false;

        for (counter = 1; counter < len - 1; 
                          counter++)
            if (isVowel(pStr[0]))
            {
                foundVowel = true;
                break;
            }
            else
                pStr = rotate(pStr);

        if (!foundVowel)
            pStr = pStr.substr(1, len) + "-way";
        else
            pStr = pStr + "ay";
    }

    return pStr;
}
Continuing with the above I've changed the breakString function to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string breakString(string pStr)
{
    string rStr1;
    string rStr2;
    string rStr;

    int i=pStr.find(" ");        //find first space
    rStr1=pStr.substr (0,i-1);   //get first word
    rStr2=pStr.substr (i+1);     //get rest of sentence after space


    // remove leading space from rStr2;

    if (rStr2 = "")
        return pigLatinString(rStr1);
    else
        return pigLatinString(rStr1) + " " + breakString(rStr2);

}


but now run into problems with the if statement.

could not convert `(&rStr2)->std::basic_string<_CharT, _Traits, _Alloc>::operator=[with_CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>](((const char*)""))' to `bool'
OK I've got the breakString function to kind of work and the program compiles now but only translates one word again.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string breakString(string pStr)
{
    string rStr1;
    string rStr2;
    string rStr;

    char i = pStr.find(" ");        //find first space
    rStr1 = pStr.substr (0,i-1);   //get first word
    rStr2 = pStr.substr (i+1);     //get rest of sentence after space


    // remove leading space from rStr2;

    if (i = pStr.find(" "))
        return pigLatinString(rStr1);
    else
        return pigLatinString(rStr1) + " " + breakString(rStr2);

}


input "Does this work properly?"
output "oe-Day"
Last edited on
I've got it to not drop the 's' in Does, I know the next problem is in the if (i = pStr.find(" ")) statement but I'm cross eyed from looking at it for so long. I'll pick back up on it in the morning in the mean time any suggestions on fixing the if/else statement are greatly appreciated.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string breakString(string pStr)
{
    string rStr1;
    string rStr2;
    string rStr;

    int i = pStr.find(" ");        //find first space
    rStr1 = pStr.substr (1,i-1);   //get first word
    rStr2 = pStr.substr (i+1);     //get rest of sentence after space


    // remove leading space from rStr2;

    if (i = pStr.find(" "))
        return pigLatinString(rStr1);
    else
        return pigLatinString(rStr1) + " " + breakString(rStr2);

}
hello KLSlim,

This might be a simplier approach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <sstream>

string breakString(const string &pStr)
{
  std::string result;
  std::stringstream ss(pStr);

  while(ss.good())
  {
    if(not result.empty())
      result += " ";

    std::string s;

    ss >> s;
    result += pigLatinString(s);
  }
  return result;
}
I don't really follow your suggestion even after having a co-worker explain it to me. I tired changing the if/else statement to:

while (i = pStr.find(" "))
{
return pigLatinString(rStr1) + " " + breakString(rStr2);
}

but it just crashes without translating anything, I can't get it to repeat till the whole sentence is translated.
KLSlim wrote:
I don't really follow your suggestion even after having a co-worker explain it to me.
well, the std::stringstream breaks the string for you.


pStr.find(" ") returns std::string::npos (which is -1) in case it doesn't find the space.

Change if (i = pStr.find(" ")) to if(std::string::npos == i)
Taking a shot in the dark here I commented out my function and inserted yours but now I get a bunch of errors during compile

1
2
3
"94 variable `std::stringstream ss' has initializer but incomplete type "
"96  request for member `good' in `ss', which is of non-class type `std::stringstream ()(std::string)' "
"103  no match for 'operator>>' in 'ss >> s' "
I couldn't figure out what was wrong with your function so I've went back to mine. Not that I can get it to work either but at least I know where the problem is, just haven't figured out how to fix it. When it gets to the if/else statement it only executes the if part and never runs the else part because if (i = pStr.find(" ")) is always true.

I've found probably a dozen ways to either translate the first word or crash it completely trying to get it to execute the else statement, but nothing to get it to execute the else statement.
Last edited on
My co-worker has point me towards determining if rStr2 is an empty string for the if statement. I've tried
if (rStr2.empty()) crashes the console
if (!rStr2.empty()) only translates the first word
if (rStr2 == "") crashes the console

I've read http://www.cplusplus.com/reference/string/string/empty/ and a bunch of other web pages but I can't figure this out.
Last edited on
Ok this works but I don't understand what the if (std::string::npos == i) is doing to make it work. Lastly I need it to move punctuation to the end of the string.

Input "Does this work properly?"
Output "oes-Day is-thay ork-way operly?-pray" (what I'm getting with the function below)
Needs to be " "oes-Day is-thay ork-way operly-pray?"

I tried adding char p = pStr.find("."||"?"||"!"); but it doesn't find any punctuation.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string breakString(string pStr)
{
    string rStr1;
    string rStr2;
    string rStr;

    int i = pStr.find(" ");        //find first space
    rStr1 = pStr.substr (0,i);   //get first word  
    rStr2 = pStr.substr (i+1);     //get rest of sentence after space


    // remove leading space from rStr2;

     if (std::string::npos == i)
          return pigLatinString(rStr1);
     else
          return pigLatinString(rStr1) + " " + breakString(rStr2);
  
}
Ok this works but I don't understand what the if (std::string::npos == i) is doing to make it work.
I said it already the function find() returns std::string::npos if it can't find anything (since 0 is a valid position in the string) and so yes if (i = pStr.find(" ")) is always true if the space isn't at the first position.

always avoid an expression like that if(x = y) // assignment inside if is a no go!


Taking a shot in the dark here I commented out my function and inserted yours but now I get a bunch of errors during compile
did you #include <sstream> ? it worked fine for me

for punctuation you can use ispunct() http://www.cplusplus.com/reference/clibrary/cctype/ispunct/

the function empty() as is doesn't crash. there must be something wrong before that.
Topic archived. No new replies allowed.