I am making a gibberish translator where you input a word and the console outputs the word in gibberish. The parameters of the gibberish language are if the word has any vowels in it you put "ab" infront of that vowel. For example "Hello" in gibberish would be "H-ab-ell-ab-o". Although i'm having a problem (Please go easy on me if you find this code messy or not well written. Im just learning)
This is my code:
int quit = 2;
int i;
bool vowel;
string word;
string letter = &word[int (i)];
void translation() {
cout << "Enter a word: " << endl;
cin >> word;
for (int i = 0; i <= 20; ++i) {
if (letter == "a") {
cout << "ab" << letter;
}
if (letter == "e") {
cout << "ab" << letter;
}
if (letter == "i") {
cout << "ab" << letter;
}
if (letter == "o") {
cout << "ab" << letter;
}
if (letter == "u") {
cout << "ab" << letter;
} else {
cout << letter ;
}
}
}
void again() {
cout << "Enter 1 to translate another word, Enter 0 to quit" << endl;
cin >> quit;
}
int main() {
while (quit >= 1) {
translation();
again();
}
return 0;
}
Say, when it prompts you to put in a word like this:
Enter a word:
You put in the word Hello, it should output this:
Enter a word:
Hello
Habellabo
Enter 1 to translate another word, Enter 0 to quit
But my program outputs this:
Enter a word:
hello
Enter 1 to translate another word, Enter 0 to quit
Why isn't it outputting the translated word?
string letter = &word[int (i)]; is some strange code, and invokes UB because the char* may not be null terminated. It is the equivalent of string letter = &word[0]; and you are taking the address of the reference to char returned from the operator[]. Also, using double quotes is wrong "a" is a string literal. You want single quotes to compare with char.
Change your code to the following:
for (int i = 0; i < word.size(); ++i) {
if (word[i] == 'a') {
cout << "ab" << word[i];
}
if (word[i] == 'e') {
cout << "ab" << word[i];
}
if (word[i] == 'i') {
cout << "ab" << word[i];
}
if (word[i] == 'o') {
cout << "ab" << word[i];
}
if (word[i] == 'u') {
cout << "ab" << word[i];
} else {
cout << word;
}
Try this instead :
string letter;
...
for (int i = 0; i <= word.length(); ++i) {
letter = word[i];
if (letter == "a") {
cout << "ab" << letter;
}
...
The letter variable has to be updated at each iteration, if not it remains empty.
Also, as mentioned in other answers, it would be a better choice, as you are iterating through characters one by one, to use the char type for the letter.
string letter = &word[int (i)];
i is global variable and is initialized to 0. But the problem is the with the string word. It is an empty string. &word[0] yields you the location of \0 character. So, letter is initialized as an empty string. So, you are actually hitting the final else statement and nothing is printed as the letter is empty as well.
You define string letter = &word[int (i)];. This doesn't do what you seem to think. It uses the value of i at the time the statement executes. Changing i later will not change the value of letter. You need to explicitly evaluate word[i] inside the loop. Also, comparing vs "a", "e", etc. compares strings, when you really want character comparison. Try single quotes instead of double quotes, i.e. 'a', 'e', etc.
Related
For example, if I wanted to find the number of times that the word "MY" appears in a user-inputted sentence, how would I do that? Is it even possible to do this if I'm reading in the sentence one character at a time with a while-loop?
Sample input would be something like: "My house is here"
My current output is:
Number of words.........4
Number of uppercase letters.........1
Number of lowercase letters........12
Number of vowels.........6
Number of substring MY.........0
where number of substring MY should be 1.
Here's what I currently have:
#include <iostream>
#include <string>
#include <cstring>
#include <iomanip>
using namespace std;
bool isvowel(char c) {
if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
return true;
} else {
return false;
}
}
int main() {
char c;
int words = 0;
int upperCount = 0;
int lowerCount = 0;
int vowels = 0;
int my = 0;
cout << "Enter a sentence: ";
while (cin.get(c), c != '\n') {
if (isupper(c)) {
upperCount++;
}
if (islower(c)) {
lowerCount++;
}
if (isspace(c)) {
words++;
}
if (isvowel(c) == true) {
vowels++;
}
if (c == 'M' || c == 'm') {
if (c+1 == 'Y' || c+1 == 'y') {
my++;
}
}
}
cout << left << "Number of words" << setfill('.') << setw(10) << right << words + 1 << endl;
cout << left << "Number of uppercase letters" << setfill('.') << setw(10) << right << upperCount << endl;
cout << left << "Number of lowercase letters" << setfill('.') << setw(10) << right << lowerCount << endl;
cout << left << "Number of vowels" << setfill('.') << setw(10) << right << vowels << endl;
cout << left << "Number of substring MY" << setfill('.') << setw(10) << right << my << endl;
system("Pause");
return 0;
}
This can be done in many ways, you almost have one. I will not give you the exact solution but you can try something like this: (written in Java)
// String sentence = "My house is here";
// word = "My"
private int getWordCount(String sentence, String word) {
char[] charArr = sentence.toCharArray();
String currWord = "";
int count = 0;
for(char c : charArr) {
if(c != ' ') { currWord += c; } // if c is not space it gets appended to the current word
else {
if(currWord.toLowerCase().equals(word.toLowerCase())) {
count++;
}
currWord = "";
}
}
return count;
}
Keep a track of the current string. If the current character is not a whitespace, append it to the string; else, the string becomes empty.
For each string, you could compare it to the target string. This comparison will have O(n) complexity, where n is the length of the string.
To optimise it further, you could build a trie for the target string. Since you're already processing one character at a time, the string matching could be done in O(1) instead of O(n).
The program takes in a word given by the user and translates that to pig latin. I've gotten everything to work almost perfectly, but have run into two bugs. The first of which is when translating words that begin with consonants say "count", the output is "ounttcay" instead of "ountcay". The second bug is that when for three letter words like "egg" or "not" the output is "egg_\377ay" or "ottn\377ay". Is there a simple way to remove that duplicate character and get rid of those numbers?
Note - Unfortunately it has to be done using a Cstring
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
int convertToPigLatin(char arr[50]);
bool isVowel(char ch);
int main() {
char userInput[50];
char answer = ' ';
do {
cout << "Enter a word to convert it to pig latin" << endl;
cin.getline(userInput, 50); //get user input
cout << "Your entered word is " << userInput << endl;
convertToPigLatin(userInput); //translate user's input into piglatin
cout << "Would you like to convert another word?" << endl;
cin >> answer;
cin.ignore(); //clear past user input
cin.clear();
} while (answer == 'Y' || answer == 'y');
return 0;
}
bool isVowel (char ch) {
switch (tolower(ch)) { //if the first character of the given input is a vowel
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return true;
default:
return false;
}
}
int convertToPigLatin(char arr[50]) {
char newArr[50];
// string conjunctions[6] = {"and","but","for","nor","yet","the"}; //list of conjunctions not to be converted
size_t arrLength = strlen(arr); //holds length of input
for (int i = 0; i < arrLength; i++) { //make sure all characters in input are lower case for easier processing
newArr[i] = tolower(arr[i]);
}
char lastChar = newArr[0]; //save the first character in case it needs to be appended
if (atoi(arr) || arr[0] == '\0') { //if the input contains a number or begins with a null character print an error
cout << "Cannot translate inputs that contain numbers" << endl;
return -1;
} else if (arrLength <= 2) { // if the input is 2 or less characters
cout << newArr << endl; //print the input as is
cout << "Boring! Try somthing more than 2 characters long" << endl;
return 0;
} else if ((strstr(newArr, "and") && arrLength == 3) || (arrLength == 3 && strstr(newArr, "but")) || (arrLength == 3 && strstr(newArr, "for")) || (arrLength == 3 && strstr(newArr, "nor")) || (arrLength == 3 && strstr(newArr, "yet")) || (arrLength == 3 && strstr(newArr, "the"))) { //if the input is more than 2 characters long
cout << newArr << endl; //print the input as is
cout << "No conjucntions try again!" << endl;
return 0;
} else { //if the given input is three characters and is not a conjunction, being translation
if (isVowel(arr[0])) { //check if input's first character is a vowel
cout << "Your word in piglatin is "<< strcat(newArr, "ay") << endl; //print that string with 'ay' at the end (i.e. egg'ay')
return 0;
} else { //else if the given input starts with a consonant
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
newArr[arrLength] = lastChar;
}
cout << "Your word in piglatin is " << strcat(newArr, "ay") << endl;
return 0;
}
}
return 0;
}
You're not terminating newArr, and the last index of the input string is arrLength - 1.
int convertToPigLatin(char arr[50]) {
// Make sure newArr is properly terminated.
char newArr[50] = {0};
// [...]
} else { //else if the given input starts with a consonant
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
}
// Do this outside the loop.
newArr[arrLength-1] = lastChar;
// No need for strcat here.
cout << "Your word in piglatin is " << newArr << "ay" << endl;
}
}
return 0;
}
You need to add the '\0' at the end of newArr because strlen does not count it so you are not copying it. strcat replaces '\0' witn 'ay\0' but you have no '\0'.
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
newArr[arrLength] = lastChar;
}
newArr[arrLength+1] = '\0';
cout << "Your word in piglatin is " << strcat(newArr, "ay") << endl;
What I want is to have a multiple-line text input, and to be able to count the number of lower-case letters, upper-case letters, periods, commas, spaces, line-breaks, and other characters in the input.
I am trying to use just one string with getline for inputs in a while loop with a running count for each punctuation category.
I just don't know how to actually figure out how many of each character type there are in each line. Given a string, how do I count the number of each type?
Here is my code so far (obviously incomplete):
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cmath>
#include <string>
using namespace std;
int main(){
cout << "This program takes any number of sentences as inputs. " << endl;
cout << "It will count the number of lower-case letters and upper-case letters. " << endl;
cout << "It will also count the number of periods, exclamation marks, spaces, end-lines, etc. " << endl;
cout << " " << endl;
cout << "Please type your text, pressing enter whenever you wish to end a line. " << endl;
cout << "Use the EOF key (CTRL + Z on Windows) when you are finished. " << endl;
string InputString; // This is the string that will be used iteratively, for each line.
int NumberOfLowerCase = 0;
int NumberOfUpperCase = 0;
int NumberOfSpaces = 0; // spaces
int NumberOfTabs = 0; // tabs
int NumberOfPeriods = 0; // periods
int NumberOfCommas = 0; // commas
int NumberOfOtherChars = 0; // other characters
int NumberOfEnters = 0; // end of line, will be incremented each loop
do {
getline(cin, InputString); // input
cout << InputString << endl; // filler just to test the input
NumberOfLowerCase = NumberOfLowerCase + 0 // I don't know what I should be adding
// (obviously not zero, that's just a filler)
} while (!cin.eof() && cin.good());
system("pause");
return 0;
}
If you simply want the number of unique characters, use a set! You can push all of your characters into the set and then just check how big the set is and you'll be good to go!
If you actually want to know how many of each character there are you can use a map (which in fact uses a set under the hood!). With the map, given some character c, you could do
std::map<char, int> counter;
//do stuff...
counter[c]++; //increment the number of character c we've found
//do more stuff...
std::cout << "Found " << counter['A'] << " A's!" << std::endl;
See these helpful functions. Here what you would do:
std::string s = /*...*/;
for(auto c : s) {
if(std::islower(c)) ++NumberOfLowerCase;
else if(std::isupper(c)) ++NumberOfUpperCase;
else if(c == ' ') ++NumberOfSpaces;
else if(c == '\t') ++NumberOfTabs;
else if(c == '.') ++NumberOfPeriods;
else if(c == ',') ++NumberOfCommas;
else ++NumberOfOtherChars;
}
Here's a very simple example I wrote very quickly. Of course there are better ways of doing it, but this should give you an idea of how you could do that. One question: Are you reading from a file or from an istream directly from the console?
int lowerCase = 0;
int upperCase = 0;
int spaces = 0; // spaces
int tabs = 0; // tabs
int newLines = 0; // end of line, will be incremented each loop
int periods = 0; // periods
int commas = 0; // commas
int otherChars = 0;
// read from istream, char by char
for (char ch; cin >> noskipws >> ch;) {
// test which classification or char ch is and increment its count
if (islower(ch))
++lowerCase;
else if (isupper(ch))
++upperCase;
else if (ch == ' ')
++spaces;
else if (ch == '\t')
++tabs;
else if (ch == '\n')
++newLines;
else if (ch == '.')
++periods;
else if (ch == ',')
++commas;
else
++otherChars;
}
cout << "Number of characters of each type:\n";
cout << "lowerCase:\t" << lowerCase << '\n'
<< "upperCase:\t" << upperCase << '\n'
<< "spaces:\t\t" << spaces << '\n'
<< "tabs:\t\t" << tabs << '\n'
<< "periods:\t" << periods << '\n'
<< "commas:\t\t" << commas << '\n'
<< "newLines:\t" << newLines << '\n'
<< "otherChars:\t" << otherChars << '\n';
I'm required to find a character entered by the user in a for loop. I'd usually do
if (sentence[i] == 'e')
but since here, 'e' will be a one letter char variable, I don't know how to get that value to be compared. I can't just enter
if (sentence[i] == thechar)
but I also can't create a variable to contain the character in between quotation marks like
char2 = "\'" + thechar + "\'";
So how do I do it in this context? I'm not allowed to use other, more effective, more advanced methods. This is a basics course. Please help!
string word;
char letter;
cout << "Enter a word\n";
cin >> word;
cout << "What letter would you like to search for?\n";
cin >> letter;
for (int i = 0; i < word.length(); i++)
{
if (word[i] == letter)
{
cout << letter << " is the " << i + 1 << "character of " << word << endl;
}
}
You can create a variable where you ask for the letter the user wants, and use that variable to compare.
To find position of chosen letter you can use std::string.find(...)
std::string str = "My house is white.";
std::size_t pos = str.find('s');
std::cout << "Position: " << pos << std::endl;
Output:
Position: 6
For more informations go to http://www.cplusplus.com/reference/string/string/find/ page.
int main()
{
char sentence;
int count;
cout << "Enter sentence: ";
cin >> sentence;
count = 0;
while ( sentence == 'b' || 'B' ) {
count++;
}
cout << "Number of b's: " << count * 1 << endl;
return 0;
}
The counting must also stop at all punctuation. I can't seem to get it to give me the correct count.
It's your while loop. The variable sentence is not changed inside the loop, so the loop may execute forever.
You may want to use std::string for a sentence and char for a character in the sentence.
Edit 1: Example
char letter;
cout << "Enter a sentence:\n";
while (cin >> letter)
{
// Check for sentence termination characters.
if ((letter == '\n') || (letter == '\r') || (letter == '.'))
{
break; // terminate the input loop.
}
// Put your letter processing code here.
} // End of while loop.
There are a couple suspicious points in your program:
char sentence;
cin >> sentence;
This looks like it would only be reading one character. You might want to getline() and save user input in a std::string
As for
while ( sentence == b || B ) {
This wouldn’t even compile since b and B are undefined. Maybe it should be
if ( cur_byte == ‘b' || cur_byte == ‘B’ )
count++
where cur_byte is some properly maintained iterator inside your string
#include <string>
Use string. string sentence; And create a for long as:
for(int i=0; i<sentence.length(); i++)
if(sentence[i] == b || B) count ++;
So simple ;) Good luck ;)
EDIT 1:
If you will only use while:
int count = sentence.length();
int count2 = 0;
while(count != 0)
{
if(sentence[count] == b||B) count2++
count--;
}
Good luck ;)
#include <iostream>
using namespace std;
int main()
{
char c;
int n = 0;
cout << "Enter sentence: ";
while (cin >> c && !ispunct(c)) if (tolower(c) == 'b') n++;
cout << "Number of b's: " << n << endl;
return 0;
}
Example:
Enter sentence: Two B or not two b, that is the question Bb.
Number of b's: 2