0

I already tried with other posts on this site, but it didn't work. I'm hoping you could help me. The problem is to erase all the vowels in the given string, then transform it to lowercase and finally to insert the '.' character before each consonant. This last one is the one that is giving me troubles.

#include <iostream> #include <cstdio> #include <ctype.h> #include <string> using namespace std; string cad1; char vowels[] = { 'A', 'O', 'Y', 'E', 'U', 'I', 'a', 'o', 'y', 'e', 'u', 'i' }; int size = sizeof(vowels) / sizeof(vowels[0]); string ToLowerCase(string text) { for (int i = 0; i < text.length(); i++) { char c = text[i]; if ((c >= 65) && (c <= 90)) { text[i] |= 0x20; } } return text; } int main() { cin >> cad1; for (int i = 0; cad1[i] != '\0'; i++) { for (int j = 0; j < size; j++) { if (cad1[i] == vowels[j]) { cad1.erase(cad1.begin() + i); } } for (int j = 0; cad1[j] != '\0'; j++) { cad1[j] = tolower(cad1[j]); } cad1 += "."; /* for (int k = 0; cad1[k] != '\0'; k++) { if (k % 2 == 0) { cad1.insert(k, 1, '.'); } } */ } cout << cad1 << endl; cin.get(); } 
6
  • 2
    Why aren't you using std::string? I see you included it. Commented Jan 23, 2014 at 0:23
  • 1
    In regards to your consonant problem - if the character is not a vowel, it's a consonant, correct? That should help you find those. Commented Jan 23, 2014 at 0:27
  • Sorry for my first answer, I misread your question a bit. I will change it a bit, then post again. Commented Jan 23, 2014 at 0:30
  • You misplaced the last for loop. It should be outside the outer for loop just before printing the contents of cad1. Remove cad1 += "."; too. Commented Jan 23, 2014 at 0:49
  • You have to check the inverse of your vowel condition. That is, for every character not contained in the vowel array, insert the character. Commented Jan 23, 2014 at 0:50

3 Answers 3

3

What you had before would have worked but I think if you include std::string you should make use of its functions. Try this:

#include <iostream> #include <string> #include <locale> using namespace std; // All of the vowels to remove const string vowels = "aeiouyAEIOUY"; // I don't know if you actually want y here // Takes a reference to the string you give it void remove_vowels(string &orig_str) { // Iterate through the string, remove all of the characters in out vowels string for (int i=0; i<orig_str.length(); ++i) { orig_str.erase(remove(orig_str.begin(), orig_str.end(), vowels[i]), orig_str.end()); } } // this function is pretty self explanatory void to_lower(string &orig_str) { transform(orig_str.begin(), orig_str.end(), orig_str.begin(), ::tolower); } void put_dots(string &orig_str) { // it is important to define max before you increase the length of the string int max = orig_str.length(); // iterate through the string, inserting dots for (int i=0; i<max; ++i) { orig_str.insert(i, string(".")); // we want to increase i again because we added a character to the string ++i; } } int main(int argc, const char * argv[]) { string name = "BILLY\n"; cout << name; remove_vowels(name); cout << name; to_lower(name); cout << name; put_dots(name); cout << name; return 0; } 
Sign up to request clarification or add additional context in comments.

2 Comments

While this will usually work, using ::tolower with a char input can have UB if the char does not meet the requirements for the paramter of ::tolower (e.g. if it is out of the range of [0, CHAR_MAX]). The C++ version can be found in <locale>.
@ZacHowland Ok, thanks for the info. I think I know what is wrong with another one of my programs now. I will update my answer.
2

You misplaced the last loop. It should be outside the outer for loop. See the modification I made to your code below:

#include <iostream> #include <cstdio> #include <ctype.h> #include <string> using namespace std; string cad1; char vowels[] = { 'A', 'O', 'Y', 'E', 'U', 'I', 'a', 'o', 'y', 'e', 'u', 'i' }; int size = sizeof(vowels) / sizeof(vowels[0]); string ToLowerCase(string text) { for (int i = 0; i < text.length(); i++) { char c = text[i]; if ((c >= 65) && (c <= 90)) { text[i] |= 0x20; } } return text; } int main() { cin >> cad1; for (int i = 0; cad1[i] != '\0'; i++) { for (int j = 0; j < size; j++) { if (cad1[i] == vowels[j]) { cad1.erase(cad1.begin() + i); } } cad1[i] = tolower(cad1[i]); } // for (int j = 0; cad1[j] != '\0'; j++) // { // } // cad1 += "."; for (int k = 0; cad1[k] != '\0'; k++) { if (k % 2 == 0) { cad1.insert(k, 1, '.'); } } cout << cad1 << endl; cin.get(); } 

Actually the for loop that converts the string to lowercase should also be moved out of the outer for loop to. See the new edited code.

If you prefer, you can actually convert to lowercase each character as you traverse them while looking for vowels. See new edited code.

5 Comments

now another problem. that code doesn't erase the letters 'Y' , 'y' or 'o'. its weird because for the input : "Codeforces" it does erase the 'o'.
The bug will occur if there are 2 vowels together. The pointer moves on after deleting the first vowel leaving the second vowel intact. I'll update the code to address this bug.
The solution is pretty simple. Change cad1.erase(cad1.begin() + i); to decrement i, Thus the pointer will stay at the new character after the delete. cad1.erase(cad1.begin() + i--);
it seems that with an " i--; " after " cad1.erase(cad1.begin() + i); " finally works
i didn't see your last comment. yep that fix the bug. thanks alvits!
0

Since you've tagged this as C++, a solution that uses the standard library's algorithms:

#include <algorithm> #include <iostream> #include <iterator> #include <limits> #include <locale> #include <sstream> #include <string> const std::string VOWELS = "AEIOUY"; // assume Y is always a vowel int main() { // read the input std::string input; while (!(std::cin >> input)) { std::cout << "Invalid input, try again\n"; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } // erase vowels input.erase(std::remove_if(input.begin(), input.end(), [&](char c) { std::locale loc; c = std::toupper(c, loc); return std::find(VOWELS.cbegin(), VOWELS.cend(), c) != VOWELS.cend(); }), input.end()); // transform to lowercase std::transform(input.begin(), input.end(), input.begin(), [](char c) { std::locale loc; return std::tolower(c, loc); }); // add . before every remaining letter std::ostringstream oss; std::for_each(input.begin(), input.end(), [&](char c) { std::locale loc; if (std::isalpha(c, loc)) { oss << "."; } oss << c; }); input = oss.str(); std::cout << "Resulting string: " << input << std::endl; return 0; } 

Example

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.