I'm new to programming, so I created number guessing game which worked perfectly but I can't seem to finish with the word guessing code. My goal is to print "Congratulations" when the guessed string is correct, but I tried many ways and I still can't make it work.
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(time(0));
int i;
const string wordList[17] = { "television",
"computer", "keyboard", "laptop", "mouse", "phone", "headphones",
"screen", "camera", "sound", "science", "programming",
"entertainment",
"graphics", "intelligent", "memory", "remote" };
string word = wordList[rand() % 17];
for(i = 0; i < word.length(); i++)
{
if(word[i] == 'a' || word[i] == 'e' || word[i] == 'i' ||
word[i] == 'o' || word[i] == 'u')
{
word[i] = '_';
}
}
cout << word << endl;
int n=0;
string x;
do
{
n++;
cin >> x;
}
while(x!=word[i]);
cout<<"Congratulations! You guessed the word!";
return 0;
}
I'd say most of your problems come down to this line:
while(x!=word[i]);
As the comments suggest, word is your modified word, not the word list. But also, i is the wrong index. So save the word index you chose earlier:
size_t wordIndex = rand() % 17;
string word = wordList[wordIndex];
Then change your do loop condition:
while (x != wordList[wordIndex]);
I'd also recommend that you don't use using namespace std;.
You could argue about the use of rand(), but it might not be worth it. Just be aware that rand() has shortcomings and better alternatives exist.
Related
So this is what I have tried doing. This is also the logic I mostly use to do word searching codes. I am basically seeing if I can find the character "g" and then I look if there are letters matching with good. If they are matching then I do count++ to count it and in the end I output my results:-
#include<iostream> //headers
#include<fstream>
using namespace std;
int main()
{
char arr[10000];
//declaration
fstream fileis;
fileis.open("fileis.txt",ios::in);
while (!fileis.eof( ))
{ //reading loop
fileis>>arr;
cout<<arr<<endl;
}
int count=0;
for(int i=0; arr[i] != '\0'; i++) //main loop
{
if(arr[i] == 'g' && arr[i+1] == 'o' && arr[i+2] == 'o' && arr[i+3] == 'd') //condition to check if the word is there
{
count++;
}
}
fileis.close();
cout<<"The word good appeared "<<count<<" times."<<endl;
return 0;
}
Here's my suggestion:
std::string word;
count = 0;
//...
while (fileis >> word)
{
// Convert word to all lower case for easy comparison.
std::transform(word.begin(), word.end(), word.begin(), tolower);
if (word == "good") ++count;
}
The above code fragment has some issues for the OP to find (such as what happens when a punctuation character is read in after "good").
By default reading a string from a stream reads in a "word", whitespace separated.
char arr[5000];
ifstream is("test.txt");
is.get(arr,5000);
int i = 0;
int j = 0;
cout << arr << endl;
char anar[5000];
while (arr[i] != '\0')
{
if (arr[i] == 'i' || arr[i] == 'a' || arr[i] == 'e' ||
arr[i] == 'o' || arr[i] == 'u')
{
++i;
}
else anar[j] = arr[i]; ++j; ++i;
}++j; anar[j] = '\0';
cout << anar << endl;
ofstream os("test.txt");
os.write(anar, sizeof(char));
cout << "written successfully" << endl;
should read the data from a file and delete the vowels from this string. After deleting vowels, it should assign the result to another string. But vowels seem strange characters and the writen file is only one character long.
How big do you think sizeof(char) is? So how many characters is this going to write?
os.write(anar, sizeof(char));
You actually have j characters in your array, so this works
os.write(anar, j);
But since you have a null terminated character array even simpler would be
os << anar;
Some other errors, look at this loop
while (arr[i] != '\0')
{
if (arr[i] == 'i' || arr[i] == 'a' || arr[i] == 'e' ||
arr[i] == 'o' || arr[i] == 'u')
{
++i;
}
else anar[j] = arr[i]; ++j; ++i;
}++j; anar[j] = '\0';
It looks like you are missing {} around the else part of the if statement. You also have an extra ++j after the while loop for some reason. Here's how it should look (I think)
while (arr[i] != '\0')
{
if (arr[i] == 'i' || arr[i] == 'a' || arr[i] == 'e' ||
arr[i] == 'o' || arr[i] == 'u')
{
++i;
}
else
{
anar[j] = arr[i];
++j;
++i;
}
}
anar[j] = '\0';
Notice how much easier these problems are to spot if you get into the habit of consistently indenting your code. You should do this.
BTW there are no C++ strings in your code, only character arrays.
A very good answer has been given by john already. So, the problem is solved.
I would like to recommend to you to learn a little bit about C++ and all the existing libraries. Especially the C++ - algorithms library is very powerful.
Look at the below program:
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
int main() {
// Open files and check, if they could be opened
if (std::ifstream is("withvowels.txt"); is)
if (std::ofstream os("withoutvowels.txt"); os)
// Copy file and remove vowels
std::copy_if(std::istreambuf_iterator<char>(is), {}, std::ostreambuf_iterator<char>(os), [](const char c) { return !((0x208222 >> (c & 0x1f)) & 1); });
}
So, in essence, we have just 3 statements: 2 times if with initializer. And then one copy_if with a lambda for vowel detection.
If you want to know more about the lambda and vowel detection you can read in one of my other posts here.
EDIT
Op asked, how to read the file into a std::string. I added a new piece of code, where I first read the complete file into a std::string and then erase/remove the vowels. The result is shown on std::cout
Please see:
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <string>
int main() {
// Open file and check, if it could be opened
if (std::ifstream is("r:\\withvowels.txt"); is) {
// Read the complete file into string variable s
std::string s(std::istreambuf_iterator<char>(is), {});
// Remove all vowels from string
s.erase(std::remove_if(s.begin(), s.end(), [](const char c) { return ((0x208222 >> (c & 0x1f)) & 1); }), s.end());
// Show result
std::cout << s;
}
}
The below program is intended to make all characters in a string lowercase, remove all vowels, and then print a full stop before every letter. For example, an input of "umbrella" would become ".m.b.r.l.l". But when I input "tour", the 'u' is not removed.
char ChangeToLow(char letter) {
if(letter <= 'Z' && letter >= 'A')
return letter - ('A' - 'a');
return letter;
}
int main()
{
string name;
cin>>name;
for (int i = 0 ; i < name.length() ; i++)
{
name[i] = ChangeToLow(name[i]);
if (name[i] == 'y' || name[i] == 'a'|| name[i] == 'u'|| name[i] == 'i'|| name[i] == 'e'|| name[i] == 'o')
{
name.erase(i,1);
}
}
for (int i = 0 ; i < name.length() ; i++)
{
cout<<'.'<<name[i];
}
}
I expect the output ".t.r" but instead it prints ".t.u.r".
Thanks in advance.
When you erase a character from the string, the remaining contents move over to fill the space. Their indexes adjust accordingly. With your tour example, it'll look something like the following:
Your loop counter, i, was incremented to 2 after you deleted the 'o' from tour, and name[i] is now 'r'. One option to avoid this behavior is to decrement i when you delete a vowel.
I have some suggestion for you. Firstly you shouldn't put using namespace std; in your code. It just adds confusion and is considered a bad practice. I think it would be also a good thing, if you would consider to learn the STL, if it is really your aim to learn C++ in depths. As for the error I think that the already posted answer shows your wrong assumptions.
#include <iostream>
#include <cstdlib>
#include <locale>
#include <set>
#include <algorithm>
int main()
{
std::string name;
std::cin>>name;
std::set<char> vowels={'a','u','i','e','o'};
std::transform(name.begin(), name.end(), name.begin(), [](auto v){ return std::tolower(v, std::locale());});
auto iter=std::remove_if(name.begin(), name.end(), [&vowels](auto v){ return vowels.find(v)!=vowels.end();});
name.erase(iter,name.end());
for (int i = 0 ; i < name.length() ; i++)
{
std::cout<<'.'<<name[i];
}
return EXIT_SUCCESS;
}
Hi I'm working a program to unscramble a set of letters and output all the words that can be made from that set of letters, for example: If i inputed the letters "vlei", the program would output "live", "evil", and "vile".
So far I have looked through the internet about this quiiiite a bit and can't find anything on my specific questions relevant to my skill level at this point (level 2 noob).
So far I have gotten as far as making all the possible combinations from the the given letters. Excluding any that are less than 7 letters, which is a problem.
This is the code I have so far:
string letter;
char newWord[7];
int main()
{
cout << "Type letters here: ";
cin >> letter;
for(int i = 0 ; i < 7 ; i++)
{
for(int j = 0 ; j < 7 ; j++)
{
for(int k = 0 ; k < 7 ; k++)
{
for(int l = 0 ; l < 7 ; l++)
{
for(int m = 0 ; m < 7 ; m++)
{
for(int n = 0 ; n < 7 ; n++)
{
for(int o = 0 ; o < 7 ; o++)
{
sprintf(newWord, "%c%c%c%c%c%c%c", letter[i], letter[j], letter[k], letter[l], letter[m], letter[n], letter[o]);
}
}
}
}
}
}
}
return 0;
}
I was wondering if anyone has any experience with anything like this, and can offer and hints or advice.
Specifically what I'm having difficulty with is how to read in a .txt file to use as a dictionary to compare words to.
Also, I was having trouble using strcmp() which is what I was planning to use to compare the scrambled words to the dictionary. So if there are any other maybe simpler ways to compare the two strings, that would be greatly appreciated.
Thanks in advance.
Hi guys, so I've just finished my program and I hope it can help someone else. Thanks a lot for all your help.
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <array>
using namespace std;
//declaring variables
int i;
int scores[531811]; //array for scores of found words
string wordlist[531811]; //array for found matched words
string word[531811]; //array of strings for dictionary words about to be read it
string tester;//string for scrambled letters that will be read in
int scorefinder(string scrab) //SCORE FINDER FUNCTION
{
int score = 0;
int x = 0;
int j = 0;
while (scrab[j])
{
char ltr = toupper(scrab[j]); //converts to all caps
//assings values to each letter and adds it to itself
if(ltr == 'A' || ltr == 'E' || ltr == 'I' || ltr == 'L' || ltr == 'N' || ltr == 'O' || ltr == 'R' || ltr == 'S' || ltr == 'T' || ltr == 'U')
x += 1;
else if(ltr == 'D' || ltr == 'G')
x += 2;
else if(ltr == 'B' || ltr == 'C' || ltr == 'M' || ltr == 'P')
x += 3;
else if(ltr == 'F' || ltr == 'H' || ltr == 'V' || ltr == 'W' || ltr == 'Y')
x += 4;
else if(ltr == 'K')
x += 5;
else if(ltr == 'J' || ltr == 'X')
x += 8;
else if(ltr == 'Q' || ltr == 'Z')
x += 10;
++j;
}
score = x;
return score;
}
int main () {
//READS IN DICTIONARY
ifstream file("words.txt"); //reads in dictionary
if (!file.is_open()){ //checks if file is being NOT read correctly
cout << "BROEKN \n"; //prints error message if so
}
if(file.is_open()){ //checks if file IS being read correctly
for(int i = 0; i < 531811; i++){
file >> word[i]; //read in each word from the file and
} //assigns each to it's position in the words array
}
//END OF READ IN DICTIONARY
cout << "Enter scrambled letters: ";
cin >> tester; //reads in scrambled letters
sort(tester.begin(),tester.end()); //sorts scrambled letters for next_permutation
while (next_permutation(tester.begin(),tester.end())){ //while there are still permutations available
for(i=0;i<531811;i++){
if ( is_permutation (word[i].begin(),word[i].end(), tester.begin())){
wordlist[i] = word[i]; //assigns found word to foundword array
scores[i] = scorefinder(word[i]); //assigns found word score to foundscore array
}
}
}
//PRINTS OUT ONLY MATCHED WORDS AND SCORES
for(i=0;i<531811;i++){
if(scores[i]!=0){
cout << "Found word: " << wordlist[i] << " " << scores[i] << "\n";
}
}
}
Well, what you need is some sort of comparison. C++ doesn´t know, what a right word in english is. So you may need a wordlist. Then you can Brutforce(that´s what you´re doing at the moment) until you find a match.
For comparing your brutforced result, you may use a .txt with as many english words as you can find. Then you have to use a FileStream for iterating through every word and comparing it to your brutforce result.
After you sucessfully unscrambled a word, you should think about your solution again. As you can see, you are limited to a specific amount of chars which is not that nice.
This sounds like an interesting Task for a beginner ;)
Suppose you have found a word list in the form of plain text file on the Internet, you may load all the words into a vector for string first.
ifstream word_list_file("word_list.txt");
string buffer;
vector<string> all_words;
while (getline(word_list_file, buffer))
all_words.push_back(buffer);
Then we want to compare the input letters with the each entry of all_words. I suggest using std::is_permutation. It compares two sequence regardless the order. But it can have trouble when the two sequence has different length, so compare the length yourself first.
// Remember to #include <algorithm>
bool match(const string& letters, const string& each_word)
{
if (letters.size() != each_word.size())
return false;
return is_permutation(begin(letters), end(letters), begin(each_word));
}
Note that I have not tested my codes. But that's the idea.
An edit responsing the comment:
In short, just use std::string, not std::array. Or copy my match function directly, and invoke it. This will be easier for your case.
Details:
std::is_permutation can be used with any container and any element type. For example:
#include <string>
#include <array>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
//Example 1
string str1 = "abcde";
string str2 = "ecdba";
is_permutation(begin(str1), end(str1), begin(str2));
//Example 2
array<double, 4> array_double_1{ 4.1, 4.2, 4.3, 4.4 };
array<double, 4> array_double_2{ 4.2, 4.1, 4.4, 4.3 };
is_permutation(begin(array_double_1), end(array_double_1), begin(array_double_2));
//Example 3
list<char> list_char = { 'x', 'y', 'z' };
string str3 = "zxy";
is_permutation(begin(list_char), end(list_char), begin(str3));
// Exampl 4
short short_integers[4] = { 1, 2, 3, 4 };
vector<int> vector_int = { 3, 4, 2, 1 };
is_permutation(begin(list_char), end(list_char), begin(str3));
return 0;
}
Example 1 uses std::string as containers of chars, which is exactly how my match function work.
Example 2 uses two arrays of double of size 4.
Example 3 even uses two different kinds of containers, with the same element types. (Have you heard of `std::list'? Never mind, just focus on our problem first.)
Example 4 is even stranger. One container is old style raw array, another is a std::vector. There are also two element types, short and int, but they are both integer. (The exact difference between short and int is not relevant here.)
Yet, all four cases can use is_permutation. Very flexiable.
The flexibility is enabled by the following facts:
is_permutation is not exactly a function. It is a function template, which is a language feature to generate new functions according to the data type you pass to it.
The containers and is_permutation algorithm do not know each other. They communicate through a middleman called "iterator". The begin and end functions together give us a pair of iterators representing the "range" of elements.
It requires more studies to understand these facts. But the general idea is not hard. Also, these facts are also true for other algorithms in the Standard Library.
Try this :
# include <stdio.h>
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of string
This function takes three parameters:
1. String
2. Starting index of the string
3. Ending index of the string. */
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
/* Driver program to test above functions */
int main()
{
char a[] = "vlei";
permute(a, 0, 3);
getchar();
return 0;
}
This question already has an answer here:
How to improve my code to correctly count unique lines?
(1 answer)
Closed 9 years ago.
I need to count the number of unique words and with my code below, it doesn't seem to be counting correctly. I am not sure what else I can do to make it work and would really appreciate any suggestions.
#include <iostream>
#include <string>
#include <set>
using std::string;
using std::set;
unsigned long countUWords(const string& s)
{
set<string> uw;
string word = "";
for(size_t i = 0; i < s.size(); i++){
bool words = (s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z');
if(words){
word += s[i];
}
else if(!words && word != ""){
uw.insert(word);
word = "";
}
}
if (word != "")
uw.insert(word);
return uw.size();
}
int main ()
{
string s;
unsigned long UWords = 0;
while(getline(cin, s)){
UWords += countUWords(s);
}
cout << UWords << endl;
return 0;
}
At the end of the for loop you need to check if word is empty. If not you need to push the content of word inside the set.
After the end bracket of the for loop, add:
if (word != "")
uw.insert(word);
As you can see it works just fine after that edit.