Pig Latin program here ---
I am really struggling to come up with a way to move punctuation back to where it belongs .... (Ello!hay needs to be be ---> Ellohay!)
I would be so grateful for some pointers. At this point, the program is good to go; all cases are accounted for (y as a consonant/vowel, q-u as a unit vs q, consonants, consonant groups, and vowels) and the capitalization of letters properly transfers. The punctuation dilemma is the downfall.
I am new to this (forum posting and c++) so please do not hesitate to let me know if I need to share more or different information.
int main()
{
string line, paragraph;
cout << "\nPlease enter your string to be converted:\n";
paragraph = paragraph_get(line);
pig_paragraph = convert_paragraph(paragraph);
cout << pig_paragraph << endl;
return 0;
}
// allows \n for paragraph option
string paragraph_get(string line)
{
string paragraph;
getline(cin, line);
while (! line.empty())
{
paragraph += line + '\n';
getline(cin, line);
}
return (paragraph);
}
// grabs words out of paragraph
string get_next_word(string paragraph, short i)
{
string word;
char letter;
letter = paragraph[i];
while ( ! isspace(letter) && i < paragraph.length())
{
word = word + letter;
i++;
if (i < paragraph.length())
letter = paragraph[i];
}
return word;
}
// defines vowels
bool is_vowel(char letter)
{
bool vowel;
if (letter == 'a' || letter == 'e' ||
letter == 'i' || letter == 'o' ||
letter == 'u' || letter == 'A' ||
letter == 'E' || letter == 'I' ||
letter == 'O' || letter == 'U')
{
vowel = true;
}
else
{
vowel = false;
}
return vowel;
}
// converts words to pig_words
// leaves numbers alone
string convert_word(string word)
{
bool was_upper;
short i = 0;
string pig_word;
string first = "";
string second = "";
if (is_vowel(word[0]) == true && isalpha(word[0]))
{
pig_word = word + "yay";
}
else if ((is_vowel(word[i]) == false && isalpha(word[0])))
{
while (i < word.length() && word[i] != 'a' && word[i] != 'e' &&
word[i] != 'i' && word[i] != 'o' && word[i] != 'u'
&& word[i] != 'y')
{
first += word[i];
i++;
}
if (i > 0 && word[i] == 'u' && word[i-1] == 'q')
{
first += word[i];
i++;
}
else if (word[i] == 'y' && word[i+1] == 'a' ||
word[i+1] == 'e' || word[i+1] == 'i' || word[i+1] == 'o' ||
word[i+1] == 'u')
{
first += word[i];
i++;
}
while (i < word.length())
{
second += word[i];
i++;
}
pig_word = second + first + "ay";
}
else
{
pig_word = word;
}
return pig_word;
}
// pig latin paragraph
string convert_paragraph (string paragraph)
{
short i = 0, length;
length = paragraph.length();
string word, pig_word, pig_paragraph = "";
while (i < length)
{
word = get_next_word(paragraph, i);
i += word.length() + 1;
is_upper(word, pig_word);
pig_paragraph += pig_word + " ";
}
return pig_paragraph;
}
In function 'int main()':
19:1: error: 'pig_paragraph' was not declared in this scope
In function 'std::string get_next_word(std::string, short int)':
46:32: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
50:7: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
In function 'std::string convert_word(std::string)':
91:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
103:25: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
111:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
80:6: warning: unused variable 'was_upper' [-Wunused-variable]
You are so awesome - thank you for that!!! Seriously appreciate it!!!
The punctuation rule is essentially keeping the punctuation separated from the letters so it too doesn't go through the translation process ---
If the original statement was "Hello, Mary!" the translated statement should be: "Ellohay, Arymay!"
If this program were to run now, as-is, it would spit out "Ello,hay Ary!may".
At this point, I have taken out all attempts to accommodate this rule. My professor had mentioned something about using a process similar to dealing with whitespace--but I can't conjure up any ideas worth mentioning haha
if its not a letter, do something, is what you want.
it looks like nonletters just need to remain in their relative position, so you treat them as whitespace (they create words, eg hello,lolla is 2 words as if the , were a space), solve the word part (hello) and put the 'delimiter' (the comma) back in after that.
this is a tremendous amount of code for the problem at hand... its looking good so far, but wow @ the amount of effort.
You need to preserve characters that are not part of the word. This will automatically fix the issues with punctuation.
So if your input is
Hello Mary
noting there are several spaces between "Hello" and "Mary", I'd expect the output to be
Ellohay Arymay
But instead it is
Ellohay Arymay
One way to fix this is to split the input into a sequence of words and non-words, where a word is a sequence of letters, and a non-word is a sequence of punctuation and spaces and whatever else. Collectively words and non-words are called "tokens".
So you look at every token in the input text, sequentially. If a token is a "word", translate it into Pig Latin and print the result. If you get a non-word just print it unchanged.
See this program, a heavily modified version of yours:
#include <iostream>
#include <string>
#include <cctype>
usingnamespace std;
string convert_word(string);
staticbool my_isalpha(unsignedchar c) { return std::isalpha(c); }
staticbool my_isupper(unsignedchar c) { return std::isupper(c); }
staticchar my_tolower(unsignedchar c) { return std::tolower(c); }
staticchar my_toupper(unsignedchar c) { return std::toupper(c); }
staticbool is_vowel(char c)
{
for (char v: "aeiouAEIOU")
if (c == v) returntrue;
returnfalse;
}
// NOTE(mbozzi): function signature has changed from `string convert_word(string const&)`
// to make it easier to move capital letters around in this function.
// Capital letters need to be moved around so that "Hello" will convert to "Ellohay"
// and not "elloHay".
string convert_word(string word) {
size_t i {};
string pig_word;
string first;
string second;
// NOTE(mbozzi): bounds checking added
if (word.size() == 0) return word;
// NOTE(mbozzi): Make the leading capital letter small, and remember
// whether it was done, so this can be undone near the end of the conversion.
boolconst has_leading_majuscule = my_isupper(word[0]);
if (has_leading_majuscule) word[0] = my_tolower(word[0]);
// TODO(mbozzi): Double check index arithmetic.
// Maybe word[i+1] or word[i-1] will access out of bounds,
// If i is zero or `word.size() - 1`.
// I don't see any problems but didn't look very hard.
if (is_vowel(word[0]) == true && isalpha(word[0]))
pig_word = word + "yay";
elseif ((is_vowel(word[i]) == false && isalpha(word[0]))) {
while (i < word.length() && !is_vowel(word[i]))
first += word[i++];
if (i > 0 && word[i] == 'u' && word[i - 1] == 'q')
first += word[i++];
elseif (word[i] == 'y' && is_vowel(word[i + 1]))
first += word[i++];
while (i < word.length())
second += word[i++];
pig_word = second + first + "ay";
} else
pig_word = word;
// NOTE(mbozzi): Make the first letter big again, if needed
if (has_leading_majuscule) pig_word[0] = my_toupper(pig_word[0]);
return pig_word;
}
int main()
{
for (std::string line; std::getline(std::cin, line); )
{
std::string::size_type begin = 0;
std::string::size_type end = 0;
for (begin = 0; begin < line.size(); begin = end)
{
boolconst is_word = my_isalpha(line[begin]);
if (is_word) while (end < line.size() && my_isalpha(line[end])) ++end;
elsewhile (end < line.size() && !my_isalpha(line[end])) ++end;
autoconst token = line.substr(begin, end - begin);
std::cout << (is_word? convert_word(token): token);
}
std::cout << '\n';
}
}
Oh my gosh, thank you Jonnin and Mbozzi, I appreciate the help so much! I was getting so discouraged and I now feel like I have direction. The program looks great, it was awesome getting to run it and use punctuation...felt so good! hahaha
Just a comment to assist with future programs. Before starting to code, first design the program. What's the input, what's the output, what algorithms are needed, what classes/structs are required, what data structures are needed? How would you perform the task using pen and paper? What detailed instructions would you give to someone else to do this who hasn't seen the requirement to accomplish the task? What functions are required?
Once you know/document this, then you design the program. Then code the program from the design. Compile and test frequently. As a rough rule of thumb, for the overall time to produce a program about 50% for design, 30% - 40% for coding and 10% - 20% for testing and debugging.