C++ Need some advices with Pig Latin string

Viewed 568

I need to write a sentence in Pig Latin form and I am almost done it successfuly except for 1 case and I almost give up for example : If my word starts at a\e\o\u\i the word will look like easy -> easyway , apple -> appleway

and if it doesnt start with a letter that I wrote above it will look like that: box -> oxbay , king -> ingkay

I succeed with the bolded part but in the first part with a\e\o\u\i letter at the beginning , I dont know where to put the w before and need some help with it

This is my code , thanks in advance

#include <iostream>

//Since those are used in ALL function of program, it wont hurt to set it to global
//Else it is considered EVIL to declare global variables
const int maxLine = 100;
char phraseLine[maxLine] = { '\0' };

void pigLatinString();

using namespace std;


void main()
{
    // Displayed heading of program
    
    cout << "* You will be prompted to enter a string of *" << endl;
    cout << "* words. The string will be converted into  *" << endl;
    cout << "* Pig Latin and the results displayed.      *" << endl;
    cout << "* Enter as many strings as you would like.  *" << endl;
    

    //prompt the user for a group of words or press enter to quit
    cout << "Please enter a word or group of words. (Press enter to quit)\n";
    cin.getline(phraseLine, 100, '\n');
    cout << endl;

    // This is the main loop. Continue executing until the user hits 'enter' to quit.
    while (phraseLine[0] != '\0')
    {

        // Display the word (s) entered by the user
        cout << "You entered the following: " << phraseLine << endl;

        // Display the word (s) in Pig Latin
        cout << "The same phrase in Pig latin is: ";
        pigLatinString();
        cout << endl;

        //prompt the user for a group of words or press enter to quit
        cout << "Please enter a word or group of words. (Press enter to quit)\n";
        cin.getline(phraseLine, 100, '\n');
    }
    return;
}


void pigLatinString() //phraseLine is a cstring for the word,  maxline is max length of line
{ //variable declarations
    char tempConsonant[10];
    tempConsonant[0] = '\0';
    int numberOfConsonants = 0;
    char previousCharacter = ' ';
    char currentCharacter = ' ';
    bool isInWord = 0;

    // for loop checking each index to the end of whatever is typed in
    for (int i = 0; i < maxLine; i++)
    {

        //checking for the end of the phraseline 
        if (phraseLine[i] == '\0')
        {//checking to see if it's in the word
            if (isInWord)
            {//checking to see that there wasn't a space ahead of the word and then sending the cstring + ay to the console
                if (previousCharacter != ' ')
                    cout << tempConsonant << "ay" << endl;
            }
            return;
        }

        // this covers the end of the word condition
        if (isInWord)
        {// covers the condition of index [i] being the space at the end of the word
            if (phraseLine[i] == ' ')
            {
                // spits out pig latin word, gets you out of the word, flushes the temp consonants array and resets the # of consonants to 0
                cout << tempConsonant << "ay";
                isInWord = 0;
                tempConsonant[0] = '\0';
                numberOfConsonants = 0;
            }
            cout << phraseLine[i] ;

        }
        else
        {//this covers for the first vowel that makes the switch
            if (phraseLine[i] != ' ')
            {// sets the c string to what is in the phraseline at the time and makes it capitalized
                char currentCharacter = phraseLine[i];
                currentCharacter = toupper(currentCharacter);

                // this takes care of the condition that currentCharacter is not a vowel
                if ((currentCharacter != 'A') && (currentCharacter != 'E') &&
                    (currentCharacter != 'I') && (currentCharacter != 'O') && (currentCharacter != 'U'))
                    //this sets the array to temporarily hold the consonants for display before the 'ay'
                {//this sets the null operator at the end of the c string and looks for the next consonant
                    tempConsonant[numberOfConsonants] = phraseLine[i];
                    tempConsonant[numberOfConsonants + 1] = '\0';
                    numberOfConsonants++;
                }
                else
                {// this sets the boolean isInWord to true and displays the phraseline
                    isInWord = 1;
                    cout << phraseLine[i];
                }
            }
            else
            {
                cout << phraseLine[i] ;
            }
        }

        previousCharacter = phraseLine[i];
    }
    return;
}
1 Answers

You have two conditions to consider. if your word starts with a vowel, just add "way" to the end of the word, else move the first letter and add "ay" to the end.

This is a task that can be made a lot simpler by using std::string instead of C-strings. This is because you are now no longer concerned with exceeding your length or losing the null character. It also allows easier access to the Standard Library algorithms.

#include <algorithm>
#include <iostream>
#include <string>

std::string make_pig_latin(const std::string& word) {
  std::string vowels("aeiou");
  std::string newWord(word);

  if (newWord.find_first_not_of(vowels) == 0) {
    // Word starts with a consanant
    std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
    newWord += "ay";
  } else {
    newWord += "way";
  }

  return newWord;
}

int main() {
  std::cout << make_pig_latin("apple") << '\n'
            << make_pig_latin("box") << '\n'
            << make_pig_latin("king") << '\n'
            << make_pig_latin("easy") << '\n';
}

The function above highlights how you can go about structuring your conversion. You just need to know if your word starts with a vowel or not, and take the appropriate action.

Output:

appleway
oxbay
ingkay
easyway

I did not get the impression that you have to care about words like 'phone'.

Looking through your code, you should try to do a better job at separating your concerns. Pig Latin is easier done one word at a time, but you have string splitting code and a lot of "not Pig Latin" code in your Pig Latin function. Your main can handle getting input. You should probably have a separate function to break the line up into individual words, using std::vector to hold the words would be best since it can grow on demand and doesn't have to know a specific capacity up front. You then iterate through your array of words and translate them individually. Depending on what your actual requirements are, it's possible that you don't even have to store the translated words, just print them directly to the screen.

Here's the same program, but now it can separate words. Note how the pig latin function doesn't have to change (much, I added upper-case vowels just because I didn't want to bothered converting words) in order for the added functionality to be added.

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

std::string make_pig_latin(const std::string& word) {
  std::string vowels("aeiouAEIOU");
  std::string newWord(word);

  if (newWord.find_first_not_of(vowels) == 0) {
    // Word starts with a consanant
    std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
    newWord += "ay";
  } else {
    newWord += "way";
  }

  return newWord;
}

int main() {
  std::string phrase(
      "A sentence where I say words like apple box easy king and ignore "
      "punctuation");

  std::istringstream sin(phrase);
  std::vector<std::string> words(std::istream_iterator<std::string>(sin), {});

  for (auto i : words) {
    std::cout << make_pig_latin(i) << ' ';
  }
}

Output:

Away entencesay hereway Iway aysay ordsway ikelay appleway oxbay easyway ingkay andway ignoreway unctuationpay
Related