I'm having trouble implementing a feature that counts and displays the number of vowels from a file.
Here is the code I have so far.
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>
using namespace std;
int main(void)
{int i;
string inputFileName;
string s;
ifstream fileIn;
char ch;
cout<<"Enter name of file of characters :";
cin>>inputFileName;
fileIn.open(inputFileName.data());
assert(fileIn.is_open() );
i=0;
while (!(fileIn.eof()))
{
????????????
}
cout<<s;
cout<<"The number of vowels in the string is "<<s.?()<<endl;
return 0;
}
Note the question marks in the code.
Questions: How should I go about counting the vowels? Do I have to convert the text to lowercase and invoke system controls (if possible)?
Also, as for printing the number of vowels in the end, which string variable should I use, (see s.?)?
Thanks
auto isvowel = [](char c){ return c == 'A' || c == 'a' ||
c == 'E' || c == 'e' ||
c == 'I' || c == 'i' ||
c == 'O' || c == 'o' ||
c == 'U' || c == 'u'; };
std::ifstream f("file.txt");
auto numVowels = std::count_if(std::istreambuf_iterator<char>(f),
std::istreambuf_iterator<char>(),
isvowel);
You can using <algorithm>'s std::count_if to achieve this :
std::string vowels = "AEIOUaeiou";
size_t count = std::count_if
(
std::istreambuf_iterator<char>(in),
std::istreambuf_iterator<char>(),
[=]( char x)
{
return vowels.find(x) != std::string::npos ;
}
);
Or
size_t count = 0;
std::string vowels = "AEIOUaeiou";
char x ;
while ( in >> x )
{
count += vowels.find(x) != std::string::npos ;
}
Also read Why is iostream::eof inside a loop condition considered wrong?
Related
Hi so I am creating a little program with the substr function to remove all vowels from a string and I thought I did it right but it wont show on the output. Sorry I am new to programming.
#include <iostream>
#include <string>
using namespace std;
bool isVowel(char ch);
string removeVowel(string str, char ch);
int main()
{
string str;
string str2;
char ch;
string newstr;
getline(cin, str);
newstr = removeVowel(str, ch);
cout << newstr;
return 0;
}
bool isVowel(char ch)
{
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U')
return true;
else
return false;
}
string removeVowel(string str, char ch)
{
string newstr = " ";
int i;
for (i = 0; i < str.length(); i++);
if (isVowel(str[ch]))
newstr = newstr + str.substr(ch, 1);
while (i < str.length())
return newstr;
}
Your entire removeVowel() function is coded incorrectly, I see several mistakes in it:
taking an input parameter char ch that is not actually useful for anything.
initializing newstr with " ", rather than using "", or just leaving the initial value off completely and letting std::string's default constructor handle the initialization.
using int for the loop counter, rather than using std::string::size_type (which is what str.length() actually returns).
terminating the loop prematurely with an erroneous ;.
using ch instead of i when accessing characters in str.
using a useless while loop.
This function needs to be completely re-written from scratch. Try something more like this instead:
#include <iostream>
#include <string>
using namespace std;
bool isVowel(char ch);
string removeVowels(string str);
int main()
{
string str;
string newstr;
getline(cin, str);
newstr = removeVowels(str);
cout << newstr;
return 0;
}
bool isVowel(char ch)
{
return (
ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' ||
ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U'
);
}
string removeVowels(string str)
{
string newstr;
for (string::size_type i = 0; i < str.length(); ++i) {
char ch = str[i];
if (!isVowel(ch))
newstr += ch;
}
/* alternatively:
for (char ch : str) {
if (!isVowel(ch))
newstr += ch;
}
*/
return newstr;
}
That being said, I would suggest a different implementation - using the erase-remove idiom, eg:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
std::string removeVowels(std::string str);
int main()
{
std::string str, newstr;
std::getline(cin, str);
newstr = removeVowels(str);
std::cout << newstr;
return 0;
}
std::string removeVowels(std::string str)
{
str.erase(
std::remove_if(str.begin(), str.end(),
[](char ch){
ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
return (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u');
}
),
str.end()
);
return str;
}
Ok, so I'm working on a project that requires us to translate English to Pig Latin. I was trying to kind of copy and tweak some code I found online that did the opposite because the functions kind of looked similar. In my class, we are given certain functions that have to be implemented in our code.
This has to be present in my source code:
struct Word
{
string english;
string pigLatin;
};
Function 1: Word * splitSentence(const string words, int &size); ~ Takes the English sentence as 1 string
Function 2: void convertToPigLatin(Word [] wordArr, int size); ~ Converts English to Pig Latin
Function 3: void convertToPigLatin(Word [] wordArr, int size); ~ Display
Here is the code that I have.
Edit: The problem I'm having is that I don't have wordArr declared anywhere in my code so it can't compile. I also noticed a few minor errors and changed my code a little. You'll have to excuse me I'm very tired right now.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
struct Word
{
string english;
string pigLatin;
};
Word * splitSentence(wordArr&; int &);
void convertToPigLatin (Word[], int);
void displayPigLatin (Word[], int);
int main()
{
string userInput;
int size;
cout <<"This is an English to Pig Latin translator.\n";
cout <<"Enter a sentance that you want to translate.\n";
getline(cin, userInput);
Word *wordArr = convertToPigLatin(userInput, size);
displayPigLatin(wordArr, size);
return 0;
}
Word * splitSentence(const Word [] wordArr, int &size)
{
int num = 0;
int phraseLength = userInput.length();
for (int i = 0; i < size; i++)
{
if (isspace(userInput[i]))
{
if (isspace(userInput[ i - 1]))
{
num--;
}
num++;
}
}
if (ispunct(userInput[i]))
{
if (i != (phraseLength - 1))
{
userInput.erase(1--, 1)
}
}
}
void convertToPigLatin(Word wordArr[], int size)
{
for (int i = 0; i < size; i++)
{
int stringLength;
if (i == (size - 1))
{
stringLength = wordArr[i].userInput.length();
}
else
{
stringLength = wordArr[i].userInput.length() - 1;
}
string vowel, way;
vowel = wordArr[i].userInput.at(stringLength - stringLength);
way = wordArr[i].userInput.at(stringLength - 3);
bool markV = ((vowel == 'A') || (vowel == 'a') (vowel == 'E') || (vowel == 'e')
(vowel == 'I') || (vowel == 'i') (vowel == 'O') || (vowel == 'o')
(vowel == 'U') || (vowel == 'u'));
wordArr[i].userInput.erase(stringLength - 3, 3);
if (!(markV && (way == 'w')))
{
wordArr[i].english = way + wordArr[i].userInput;
}
}
displayPigLatin(wordArr, stringLength);
}
void displayPigLatin(const Word wordArr[], int size);
{
cout << "\nHere is your phrase in PigLatin: ";
for (int i = 0 i < size; i++)
{
cout << wordArr[i].userInput << " ";
}
}
Important Note: You can only use range based for-loops in C++11 or higher if your compiler doesn't support C++11 or higher, use regular for-loops...
Given your question, you have to use this structure (It is equivalent to the one in the question):
typedef struct
{
std::string english;
std::string pig_latin;
} Word;
This is a macro which is going to be used to check if the first letter is a vowel or a consonant (Hence, !IS_VOWEL(some_char))...
#define IS_VOWEL(x) ((x) == 'A' || (x) == 'E' || (x) == 'I' || (x) == 'O' || (x) == 'U' || \
(x) == 'a' || (x) == 'e' || (x) == 'i' || (x) == 'o' || (x) == 'u')
Another function which we need to acquire only the part of the word which has letters (not symbols and numbers):
std::pair<unsigned, unsigned> GetWord(std::string word)
{
auto start = word.end();
for (auto it = word.begin(); it != word.end(); ++it)
if (tolower(*it) >= 'a' && tolower(*it) <= 'z' && start == word.end())
start = it;
else if (start != word.end() && !(tolower(*it) >= 'a' && tolower(*it) <= 'z'))
return std::make_pair(std::distance(word.begin(), start), std::distance(word.begin(), it));
return std::make_pair(start == word.end() ? 0 : std::distance(word.begin(), start), std::distance(word.begin(), word.end()));
}
And last but not least, the function to convert English to Pig-Latin (I know it is huge):
std::vector<Word> CreatePigLatinWordsFromEnglish(std::string english, bool sentence_case = true)
{
// You can break it from here to use inside another function (viz., splitSentence)
std::transform(english.begin(), english.end(), english.begin(), ::tolower);
std::stringstream english_stream(english);
std::vector<Word> words;
std::string temporary;
while (std::getline(english_stream, temporary, ' '))
words.emplace_back(Word({ temporary, "" }));
// Till here...
// From here the conversion starts...
for (auto &word : words)
{
auto const word_it = GetWord(word.english);
if (!IS_VOWEL(word.english[word_it.first]) && !std::string(std::next(word.english.begin(), word_it.first),
std::next(word.english.begin(), word_it.second)).empty())
{
word.pig_latin.append(std::string(word.english.begin(), std::next(word.english.begin(), word_it.first)));
word.pig_latin.append(std::string(std::next(word.english.begin(), word_it.first + 1), std::next(word.english.begin(), word_it.second)));
word.pig_latin.append(1, word.english[word_it.first]);
word.pig_latin.append(std::string("ay"));
word.pig_latin.append(std::next(word.english.begin(), word_it.second), word.english.end());
}
else
word.pig_latin = std::string(word.english.begin(), std::next(word.english.begin(), word_it.second)) + "way"
+ std::string(std::next(word.english.begin(), word_it.second), word.english.end());
}
// Conversion ends here...
// Changing the case from lower case to sentence case if needed...
if (sentence_case)
{
words[0].english[0] = toupper(words[0].english[0]);
words[0].pig_latin[0] = toupper(words[0].pig_latin[0]);
}
return words; // Returning the list of words we got...
}
Well, an example to demonstrate this method:
int main()
{
auto const test = "An apple a day keeps the doctor away!";
for (auto word : CreatePigLatinWordsFromEnglish(test))
std::cout << word.pig_latin << " ";
return 0;
}
Output:
Anway appleway away ayday eepskay hetay octorday awayway!
Try it out and see whether it gives you the required result...
Kind regards,
Ruks.
This question already has answers here:
How to replace all occurrences of a character in string?
(17 answers)
Closed 5 years ago.
How can I replace vowel letters with a character, for example input: asd output:.sd, so we replaced vowel letters with '.', I tried to do that, but I couldn't don't know why, here is my code:
#include <iostream>
using namespace std;
int main () {
string s;
cin>>s;
if (s=="a")
s='.';
if (s=="e")
s='.';
if (s=="u")
s='.';
if (s=="o")
s='.';
if (s=="i")
s='.';
cout<<s<<endl;
}
why nothing is changed? input = output?
You have a problem. When you read the string "s", it is equal to "asd". So when it is compared in the conditional (s=="a"), it is false. You must compare char by char. I share a possible solution:
#include <iostream>
int main()
{
std::string s;
std::cin >> s;
for (char& c: s)
{
if (c == 'a' || c=='e' || c == 'i' || c == 'o' || c == 'u')
c = '.';
}
std::cout << s << std::endl;
}
You can use std::replace_if to replace a character if it's a vowel, using std::string::find to easily figure out if the char is a vowel i.e. :
std::string s = "abcvaoi";
std::replace_if( s.begin( ), s.end( ), [] ( const char c ) {
return std::string( "aeiou" ).find( c ) != std::string::npos;
}, '.');
You may use switch case and for loop for simplicity.
using namespace std;
#include<iostream>
int main()
{
string a;
cin>>a;
for(int i=0;a[i]!='\0';i++)
{
switch (a[i])
{
case 'a':a[i]='.';
break;
case 'e':a[i]='.';
break;
case 'i':a[i]='.';
break;
case 'o':a[i]='.';
break;
case 'u':a[i]='.';
break;
}
}
cout<<a;
}
This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 5 years ago.
how do i divide a sentences in c++ like :
input from cin (He said, "that's not a good idea". )
into
He
Said
That
s
not
a
good
idea
to test whether a character is a letter, use a statement (ch >='a' && ch <='z') || (ch >='A' && ch <='Z').
You can split string by spaces then check each word if it has any characters other than A-z or not. if it has, erase it. Here's a tip :
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
std::vector<std::string> splitBySpace(std::string input);
std::vector<std::string> checker(std::vector<std::string> rawVector);
int main() {
//input
std::string input ("Hi, My nam'e is (something)");
std::vector<std::string> result = checker(splitBySpace(input));
return 0;
}
//functin to split string by space (the words)
std::vector<std::string> splitBySpace(std::string input) {
std::stringstream ss(input);
std::vector<std::string> elems;
while (ss >> input) {
elems.push_back(input);
}
return elems;
}
//function to check each word if it has any char other than A-z characters
std::vector<std::string> checker(std::vector<std::string> rawVector) {
std::vector<std::string> outputVector;
for (auto iter = rawVector.begin(); iter != rawVector.end(); ++iter) {
std::string temp = *iter;
int index = 0;
while (index < temp.size()) {
if ((temp[index] < 'A' || temp[index] > 'Z') && (temp[index] < 'a' || temp[index] > 'z')) {
temp.erase(index, 1);
}
++index;
}
outputVector.push_back(temp);
}
return outputVector;
}
in this example result is a vector that has words of this sentence.
NOTE : use std::vector<std::string>::iterator iter instead of auto iter if you are not using c++1z
I'm writing a programm which gives out the input string without its vowels.but it only gives the first charachter of the string .here is the code:
#include<iostream>
using namespace std;
int main(){
char ch;
while(cin.get(ch)){
cout<<ch;
char a=cin.peek();
while( a==65 || a==69 || a==73 || a==79 || a==85 || a==97 || a==101 || a==105 || a==111 || a==117)
cin.ignore(1 , a);
}
return 0;
}
To solve a problem like this, start by breaking the problem into smaller parts. A possible decomposition is:
Are there characters still to read from the input? No: Great, we are done!
Read in a character
Is the character a vowel? Yes: Goto 1.
Output the character
Goto 1.
Then in code, you can translate this into:
// 1) Are there characters still to read?
while (std::cin.good())
{
// 2) Read in a character
char ch;
std::cin.get(ch);
// 3) Is the character a vowel?
// For the test for a vowel, you can use something similar to
// what you have at the moment, or better still: consider
// writing a function like isVowel in #Shreevardhan answer.
if ( /* TODO: Test if the character is a vowel... */)
{
// Skip the rest of the loop and go back to 1
continue;
}
// 4) Output the good character
std::cout << ch;
// 5) Reached the end of the loop, so goto 1
}
It's a good habit to break your problem down into smaller parts. I often start a new project by first writing out a list/comments (or even drawing a flow diagram) to break up the problem into more manageable pieces.
Other answers show how to solve this problem in a more intuitive manner.
Anyway, when looking at your code consider the following:
while( a==65 || a==69 || a==73 || a==79 || a==85 || a==97 || a==101 || a==105 || a==111 || a==117)
cin.ignore(1 , a);
As you do a while loop with conditions around the value of a, and as cin.ignore(1 , a) does not change the value of a, you wont ever leave this loop unless an exception is thrown, right?
Maybe you can try to use the boost library.
#include <boost/algorithm/string.hpp>
boost::erase_all(str, "a");
Something like this
#include <iostream>
using namespace std;
bool isVowel(char c) {
c = tolower(c);
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
int main() {
char c;
while (cin.get(c))
if (!isVowel(c))
cout << c;
return 0;
}
Add your storing logic inside.
A more C++-ish code
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
string s;
getline(cin, s);
s.erase(remove_if(s.begin(), s.end(), [](char c) {
c = tolower(c);
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}), s.end());
cout << s;
return 0;
}
See a demo.