You are here:

C++/C-String in C++ & Pig Latin


i am trying to create a translator from English to Pig Latin using only <iostream> and <cstring>.

the rules are simple:
- if a word begins with a vowel, put a "way" at the end of it.
- if a word does not begin with a vowel, look for the first vowel, move everything before the first vowel to the end of the string, and then add "ay" to it.

for example, if i input 'apple', i would get 'appleway'.
for example, if i input 'blown', i would get 'ownblay'.

so far, i have managed to write a code which edits the words with a vowel at the beginning, but cannot for the life of me edit the string for which a vowel is within the word (i.e. not the starting character). if you could just tell me how to change the following code, i would much appreciate it!

#include <iostream>
#include <cstring>
using namespace std;

void PigLatin (char a[], char b[]);

void main(){
  char source[100];
  char destination[100];
  cout << "Please enter a word: ";
  cin.getline(source, 100);
  PigLatin(source, destination);
  cout << "Translation in PigLatin is: " << destination << endl;

void PigLatin (char a[], char b[]){
  if (a[0] == 'a' || a[0] == 'e' || a[0] == 'i' || a[0] == 'o' || a[0] == 'u'){
     strcpy(b, a);
     strcat(b, "way");
  if (a[0] != 'a' || a[0] != 'e' || a[0] != 'i' || a[0] != 'o' || a[0] != 'u'){
     for (int i = 0; i<(strlen(a)); i++){
        if (a[i] == 'a' || a[i] == 'e' || a[i] == 'i' || a[i] == 'o' || a[i] == 'u'){
         strncat(b, a, 10);
         strcat(b, "ay");

Good job on the first part of your PigLatin function. The next part is a bit more challenging, though.

The first thing I would do (mostly for form's sake, in this case), is make the rest of it (after your working IF statement) an ELSE clause:
   if (...)
   {  .....
   {  .....

That way if the IF clause is true, the compiler can skip the ELSE clause, which is what you want.

Now, you need to organize what you want done if the first letter is a consonant. There is more than one approach to this. You could separate the word into 2 parts, in 2 separate strings (1. everything before the first vowel, and 2. everything after and including the first vowel), and put them back together, second string first, then add "ay". Or you could count the number of consonants at the beginning of the word, then make a string of the rest, and use your counter with STRNCAT to only get the consonants added at the end. I like the first approach, because it is more versatile, so that is what I will help with here.

Think of a few examples, and see what needs to be done; for "big", you need to have "ig" in a string, and concatenate to it "b" and "ay", ending in "igbay". For "thing", you need "ing" in a string, and also "th" in a string, then STRCAT them and "ay".

This is where the structure of your nested loops is key. First you want to decide on your outer loop. I used a WHILE loop:
   int i=0;
   while (i<(strlen(a)))

This isn't the only way to do it, but it gives a measure of control. It loops once for each letter in the string (unless you increment i within one of the inner loops, which is convenient here). Now, you can set up an inner loop to test each letter as it comes and decide what to do depending on if it's a consonant or a vowel.
First, set up a conditional loop so that if the letter in question is a vowel, it puts that letter and the rest of the string into another string (you can use b or a new one - I used a new one I defined earlier as CHAR after_consonants [100]). Within this loop, increment i each time so the WHILE clause won't trigger again once it is done - after all, you are done with the word now. We know this loop wont be triggered the first time through, because this part of the program - all in the ELSE clause of the whole function - doesn't even trigger when the first letter of the string is a vowel.
So far, the whole function including your successful part looks like this (numbered for reference):

1)    if (first letter is a vowel)
2)        cout << string+"way";
3)    else
4)        while(not at end of string)
5)        {
6)          if(member of string is a vowel)
7)          put the rest of the string in another string (after_consonants for example)

So, nothing in the ELSE section gets triggered if the first letter is a vowel. If the first letter is a vowel, it skips from 2) to 12).
Now you need to determine what happens if it is a consonant. Well, store that in a string too - I used b for this. So, continuing:

8)          else
9)          put the consonant at the end of a consonant storage string (b for example)
10)       end the while loop (4) - if i<(strlen(a)), it loops through it again.
11)   end the else loop (3)
12)   concatenate your strings and return them

Step 7 is a little tricky. It triggers when you run into your first vowel (that isn't the first letter of the string of course). Set up another loop here that adds the current letter to the end of after_consonants (our string to hold the back part of the original string), then increments i. You want to increment i each time so that when it checks the WHILE loop again, it sees you are at the end of the string.
Now, to add the current member of the string to after_consonants, I would normally use APPEND(after_consonants, a[i]). However, that doesn't follow your rules - it's not in <iostring> or <cstring>. So, what I did to get around it was create another string I defined:

   char buffer[1];

It needs to be only one unit in size. Since you can't STRCAT a char to the end of a string (it must be a char array), make a one char array, lol. So:

   buffer[0] = a[i];
   strncat(after_consonants, buffer, 1);

will add a[i] (the current character of the array) to the end of after_consonants, which I used to store the rest of the string after the consonants. I used STRNCAT to avoid any possibility of garbage in the string.

Tip: In order for step 7 to work, it must be a FOR loop that uses i as a counter - but remember not to initialize i to 0, because we don't know what element of the array we are going to be looking at by then. So:

   for (i; i<(strlen(a)); i++)
       buffer[0] = a[i];
       strncat(after_consonants, buffer, 1);

That is actually your entire step 7. You should be able to figure out step 9 from that. Keep in mind though that you do not want to put the rest of the word in your storage string (b is what I used for consonants), just one char. You will need to increment i only once here. Then it's back to the WHILE loop (step 4) to check the condition.

For step 12, you need to add the consonant string to the end of the after_consonant string. Then add "ay" to the end of that. Then make sure it is stored in b, and return. All done.

A couple of notes:
Define your new strings at the top. You will also want to initialize b (you didn't need to for the part you had working, but it can become problematic later). It's a good practice to initialize variables and arrays upon creation, but you don't usually need to. In this case, though, I needed to with b, or I got garbage in my result. So:

   void PigLatin (char a[], char b[])
       char after_consonants[100];
       char buffer[1];

       for (int j=0; j<100; j++)
         b[j] = '0';          //this sets all members of b to the null character
         after_consonants[j] = '0';   //optional - does the same for after_consonants

then your code.

I hope this helps. Work through it as best you can, and use plenty of test code, eg.:
   cout << "I am expecting a list of consonants here: " << b << endl;
   cout << "this should be a vowel first: " << buffer[0] << endl;

You can print to screen any time, so you can see what's going on with your variables and isolate problems. Also, use comments (//) to mark blocks of code such as loops so can tell at a glance what that part of the program is supposed to be doing.
Make sure your program is pausing at the end of the program so you can see what happened. In my compiler, SYSTEM("PAUSE"); works, but it can vary. So:

   int main()

I put that at the end of almost every program.

Let me know if you need more help - just try to work out what you can first and show me what you have if you get stuck. Happy coding.


All Answers

Answers by Expert:

Ask Experts


Oshi Jager


I can: - help debug code, or make it more efficient - help with concepts, key terms and commands, and object design/inheritance - give suggestions for subroutines or object calls - suggest overall organization techniques and/or data organization I have a fairly good concept of program flow, so if you have ideas, but don't know how to get started... I've had to do a lot of that, and I can help.


Primarily, 36 units in Computer Science at university. Also, I started programming games in C and C++ back when the Commodore 64 was the best game machine out there, and that makes me old... for those of you who don't know the reference. I have intermittently kept up with my programming, so try me out.

As of 2 years ago: Association for Computing Machinery (ACM)

Related classes at Cal State University: - Object Oriented Programming (3 units) [basically C/C++] - Database Design and Implementation (3) [all theory and SQL oriented] - Discrete Mathematics (3) [pure theory] - Computer Organization (3) [cpu functionality and programming] - Data Structures (3) [in C++, but also in general theory] - Computer Architecture (3) [the PC from top to bottom] - Java Programming (3) - Programming Languages (3) [history] - Telecommunications and Networking (3)

©2016 All rights reserved.