Explain this code to me?

So upon researching online for code I came across one that works great, but I don't understand completely. I just want to understand what is happening throughout the code, why this person did some of the things they did. Does that make sense? I'm seeing a lot of things I haven't learned yet.

The program converts english phrases to pig latin.

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

using namespace std; 

bool isVowel(char); 
string pigIt(const string&); 

int main(int argc, char *argv[]) { 
    string line,word; 
    stringstream ss; 

    while (true) { 
        cout << "> "; 
        getline(cin,line); 
        if (line.size() > 0) { 
            ss.clear(); ss.str(line); 
            cout << ": "; 
            while (ss.good()) { 
                ss >> word; 
                cout << pigIt(word) << " "; 
            } 
            cout << endl; 
        } 
    } 
    return 0; 
} 

string pigIt(const string &w) { 
    string pig = w; 
    if (isVowel(w[0])) { 
        pig += string("way"); 
    } else { 
        size_t p = 0; 
        while (!isVowel(pig[++p])); 
        pig += (pig.substr(0,p) + string("ay")); 
        pig.erase(0,p); 
    } 
    return pig; 
} 

bool isVowel(char c) { 
    static const string vowels("aeiou"); 
    return (vowels.find(tolower(c)) != string::npos); 
} 
Last edited on
I'm not going to go through the entire code and explain it line by line.
If you have specific questions, please post the line number and what you don't understand about that line.
Sorry, I figured it easiest to just post the whole code, but it makes sense that the other way is easier! Maybe I was just being lazy! Here are the things I'm not understanding:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <sstream> //Why use this and the following?
#include <cctype> 

string pigIt(const string&); //Why const?

int main(int argc, char *argv[]) //Why does this need a pointer? (that's a pointer, right?)
{ 
    stringstream ss; //So I assume this has connection to the <sstream>, but what does this do?

        if (line.size() > 0) //line size gets the number of characters in a string, right?
{ 
            ss.clear(); ss.str(line); //Why do we clear the string? Is that what ss.clear does?
            cout << ": "; 
            while (ss.good())//Variable? (ss.good)
 { 
                ss >> word; //What does the command ss do? Is it another input command?

string pigIt(const string &w) //again, how do you know when to use a constant?

        pig.erase(0,p); //is p a single character place holder for the first(0) character?
  
    static const string vowels("aeiou"); //What is static constant?
    return (vowels.find(tolower(c)) != string::npos); //I know npos means no positino, but how does this line work? Is it an if statement?
} 
For main, http://crasseux.com/books/ctutorial/argc-and-argv.html

The use of stringstream is to have something equivalent to writing to an input/output buffer (cin or cout) or a filestream, but do it in memory. For details about the functions of stringstream see http://www.cplusplus.com/reference/sstream/stringstream/

You use constant in pigIt if you want to make sure you don't modify the input
Thanks for identifying your questions.
All line references are to your current post, except where noted.

line 1: because you use stringstrem at line 8.

line 4,18: As ats15 said, tells the compiler you don't modify w within pigIt. The compiler will flag an error if you attempt to modify a const argument. This has two benefits. 1) It protects against accidently modifying something you didn't intend to modify. 2) It lets the compiler generate more efficient code since the compiler doesn't have to worry about saving any changes to the variable.

line 6: argv is actually an array of pointers (note the []). argv[0] is a pointer to a character array containing the program file name. argv[1] is a pointer to a character array containing the first argument. A null pointer follows the last command line argument. argv should be considered const although most compilers (for historical reasons) won't flag an error if you don't declare argv as const.

line 8: ats15 gave you a reference to stringstring. Yes, you need the <sstream> header if you use stringstream. stringstream is convenient if you you have a string containing data fields and want to parse it a field at a time using the >> operator. stringstream can also be use to build output into a string using the << operator.

line 10: correct.

line 12: Yes, clear clears the string. clear is needed here because ss was declared outside the loop (orig line 15). If you don't clear it, ss would just accumulate everything you output to it.

line 14: ss.good() is a function call (note the () ). It tests the good bit for the stream. stream inherits from iostream, so it has all the properties of an iostream. See the documentation for iostream for what can set/clear the the good/bad bit.

line 16: Inputs a string (word) from the current line. This is just like an input operation from cin, except that it uses a string (line) as the source of bytes to read instead of a file. Note that ss was constructed from line at line 19 in your original post.

line 20: No. p is an unsigned int. See line 36 in orig code. It functions as an index.

line 22: static tell the compiler to allocate vowels only once. i.e. it is not created each time isVowel() is entered. You can think of it something like a global in that it always exists, but is only visible to isVowel.

line 23: This is a boolean expression. It evaluates to true or false. If find returned something other than npos, then the result of the expression (and the function) is true.

edit: removed line 12 comment per Dante12129's post.


Last edited on
ss.clear() doesn't clear the contents of string, it sets the error state flags, with the default being goodbit. If you wanted to clear the stringstream, you would do ss.str("");

Reference to std::basic_ios::clear (where all the streams get the clear() method from): http://en.cppreference.com/w/cpp/io/basic_ios/clear
Thank you all for the comments and explanations! You've helped to clear up a lot of the confusion! :)
Topic archived. No new replies allowed.