C++ Evil Hangman Implementation problems - c++

I'm trying to implement a version of Evil Hangman where the game changes word depending on what is the most difficult to guess. However I'm getting an error and I just can't seem to spot it. It's probably something stupid but it feels like I've been staring at it for hours. I've narrowed it down to this via print statements before it crashes:
vector<string> newWords;
bool inword=false;
int place=0;
cout<<"here 1";
if(!remove){//remove true so only keep words that dont have letter in them.
cout<<" in if(remove) \n";
for(int i=0;i<wordsLeft.size();i++){
cout<<" in first loop \n";
for(int n=0;n<(wordsLeft[i].length())&&!inword;n++){
cout<<"in second loop n: "<<n<<" i: "<<i<<" inword: "<<inword<<" length: "<<wordsLeft[i].length()<<endl;
if(wordsLeft[i].at(n)==letter){
inword=true;
}
}
if(!inword){//if false then add word meaning words not containing letter array
newWords[place]=wordsLeft[i];
place+=1;
}
else{
inword=false;
}
}
cout<<"here 2";
}
else{//remove false so only keep words that have letter in them.
cout<<"here 3";
for(int i=0;i<wordsLeft.size();i++){
for(int n=0;n<(wordsLeft[i].length())&&!inword;n++){
if(wordsLeft[i].at(n)==letter){
inword=true;
}
}
if(inword){//if true then add word meaning words containing letter array
newWords[place]=wordsLeft[i];
place+=1;
inword=false;
}
}
cout<<"here 3.5";
}
cout<<"here 4";
index=place;
wordsLeft=newWords;
}

I can't add comments yet, but based on your comment it's saying that wordsLeft wasn't declared in the scope, that means that wordsLeft in your first for loop is inaccessible. You may have definied that variable elsewhere in another function or it may be private.
Post where wordsLeft was definied and for next time: Post the error message/code

Related

cout doesn't works properly on my program, can somebody help me?

enter image description hereI am using the STL in c++ and inside a bucle the cout doesn't prints correctly a float.
my program ads values to a vector and then passes it to a function to see if the condition exist, actually it works perfectly but just the cout doesn't word, I already tried using printf() but it gave the same result.
note:please algo give me feedback on my question is the first time i do one and English is not my natal language
my code:
#include<bits/stdc++.h>
#include<vector>
using namespace std;
void isthereanumber(vector<float> array);
int main(){
string ans;vector<float> array;float number;
do{
fflush(stdin);
cout<<"insert a value for the vector: "<<endl;
cin>>number;
array.push_back(number);
fflush(stdin);
cout<<"would you like to keep adding values to the vector? "<<endl;
getline(cin,ans);
}while(ans.compare("yes")==0);
isthereanumber(array);
return 0;
}
void isthereanumber(vector<float> array){
float suma =0;
for(vector<float>::iterator i=array.begin();i!=array.end();i++){
for(vector<float>::iterator j=array.begin();j!=array.end();j++){
if(i!=j){
suma = suma+array[*j];
}
}
if(suma=array[*i]){
cout<<"there is a number that the addition of every number in the array except the number is equal to the number \n";fflush(stdin);
cout<<"the number is: "<<suma;/*here is the cout that doesnt works properly or perhabs is something else i don't know*/
return;
}
}
cout<<"there is not a number with such a condition: ";
return;
}
As stated by cleggus already there are some issues present. Those need to be adressed first. After that there's a logical error in that suma just keeps growing.
Given the input 5,5,10 once we test for 10 we would like suma to be set to 0 again for it to work but it will be something like 30 now instead.
That can be solved by moving suma inside the outer loop.
Working example for input 5,5,10: https://godbolt.org/z/gHT6jg
I think you may have a couple of issues...
In your for loops you are creating iterators to the vector, but rather than just dereferencing them to access the indexed element you are dereferencing them and then using that as an index to the same vector.
Also Your last if statement has an assignment = rather than a comparison ==.
I believe this is closer to what you are trying to achieve (sorry I haven't had time to compile and check):
for(vector<float>::iterator i=array.begin();i!=array.end();i++){
for(vector<float>::iterator j=array.begin();j!=array.end();j++){
if(i!=j){
suma = suma+*j;
}
}
if(suma==*i){
cout<<"there is a number that the addition of every number in the array except the number is equal to the number \n";fflush(stdin);
cout<<"the number is: "<<suma;/*here is the cout that doesnt works properly or perhabs is something else i don't know*/
return;
}
}

Can't access my vector variables in different conditions

I'm trying to do creating objects in a one condition and listing this objects in another condition, but it doesn't work.
void fillVector(vector<Account>& newcreateAccObj){
string name;
string password;
cout<<"Enter your surname:"<<endl;
cin>>name;
cout<<"Enter your password:"<<endl;
cin>>password;
Account newAcc(name,password);
newcreateAccObj.push_back(newAcc);
cout<<endl;
}
This works fine.
void printVector(vector<Account>& newcreateAccObj){
unsigned int size=newcreateAccObj.size();
for(unsigned int i=0;i<size;i++){
cout<<"Account"<<i+1<<endl;
cout<<"-----------"<<endl;
newcreateAccObj[i].getId();
newcreateAccObj[i].getName();
cout<<endl;
}
}
This works fine too when I execute these 2 functions in same condition.
But when I do this:
int main(){
int whileCondition=-1;
string girisSecim;
vector<Account> createAccObj;
while(whileCondition==-1){
cout<<"--------------------------------------------------------"<<endl;
cout<<"??????????????????????????????????????????????????????"<<endl;
cout<<"1-create acc 2-transferring"<<endl;
cout<<"3-enter acc 4-exit"<<endl;
cout<<"--------------------------------------------------------"<<endl;
cin>>girisSecim;
if(girisSecim=="1"){
fillVector(createAccObj); //BURDA OBJE OLUSTURULUYOR
}
else if(girisSecim=="2"){
printVector(createAccObj);
}
else if(girisSecim=="3"){
}
else if(girisSecim=="4"){
return 0;
}
else{
cout<<"Hatali tuslama."<<endl;
}
whileCondition=0;
cout<<"Programa devam etmek icin -1'i, cikmak icin herhangi bir seyi tuslayiniz."<<endl;
cin>>whileCondition;
}
Edit: I edited the main part.
I choose option 1 first. I create my object and returning the select menu, after that I choose option 2 and it gives me a blank output.
follow the lifetime of createAccObj.
it seems like you do not send the same vector to both functions.
I will have a guess, your code looks like this:
while (input}(
vector<Account> createAccObj;
if(input=="1"){
fillVector(createAccObj);
}else if(input=="2"){
printVector(createAccObj);
}
here, on each iteration, new vector is created, so when you try to print, you print empty vector.
If this is the case, simply, remove the vector deceleration outside the loop.
Edit:
looking into the code again, seems like you forgot cout in newcreateAccObj[i].getId(); and newcreateAccObj[i].getName();

Break from a while loop repeating

What I am trying to achieve is the user enters a value followed by a measurement. this is then placed either as smallest, largest or in between.
A count of how many values have been entered is kept. and the total of all the values in meters.
Initially the program works but when I type the break character, the program repeats the same line. What I do want is the program to end printing lines 129 and 130. Here's my code.
int main()
{
double var1; //the variable entered by the user
double sum; //the sum of calculations to convert into centimeters
double total=0/100; //converts to meters
int e=0; //will be used to count how many numbers were entered
string measurment; //the users desired measurement input
string centimeter = "cm";
string meter = "m"; //these are used to compare the users measurement input
string inch = "in";
string foot = "ft";
char d='t';//this will be used to break the loop (t is just the default)
char a='a';
char c='c';
char m='m';//char a-f are used for a switch
char i='i';
char f='f';
double small=20000;
double large=0;
double cm=1;
double me=100;//centimeters
double in=2.54; //centimeters
double ft=12; //inches
//the following code creates a break when the character is entered.
while(d!='q')//break rule
{
if(false)
break;
cout<<"please enter a double and a unit of measurement."<<'\n';
cin >>var1>>measurment;
e++;
// the following portion of code sets the char for the switch which
// which will be used in the following code. it will also perform the
// the math which will calculate between distances.
if (measurment==centimeter)
{
a=c;
sum=var1*cm;
}
else if (measurment==meter)
{
a=m;
sum=var1*me;
}
else if (measurment==inch)
{
a=i;
sum=var1*in;
}
else if (measurment==foot)
{
a=f;
sum=(var1*ft)*in;
}
else
{
cout<<"I am sorry. But, that is not a valid measurement for this program."<<'\n';
}
//the following code places the number entered into either
//smallest largest or in between.
if (sum<small)
{
small=sum;
total+=sum;
switch(a){
case'c':
cout<<small/cm<<centimeter<<" is the smallest measurement so far."<<'\n';
break;
case'm':
cout<<small/me<<meter<<" is the smallest measurement so far."<<'\n';
break;
case'i':
cout<<small/in<<inch<<" is the smallest measurement so far."<<'\n';
break;
case'f':
cout<<(small/in)/ft<<foot<<" is the smallest measurement so far."<<'\n';
break;
}
}
else if (sum>large)
{
large=sum;
total+=sum;
switch(a){
case'c':
cout<<large/cm<<centimeter<<" is the largest measurement so far."<<'\n';
break;
case'm':
cout<<large/me<<meter<<" is the largest measurement so far."<<'\n';
break;
case'i':
cout<<large/in<<inch<<" is the largest measurement so far."<<'\n';
break;
case'f':
cout<<(large/in)/ft<<foot<<" is the largest measurement so far."<<'\n';
break;
}
}
else if(sum>small&&sum<large)
{
total+=sum;
switch(a){
case'c':
cout<<var1<<centimeter<<" is neither the longest or shortest measurement."<<'\n';
break;
case'm':
cout<<var1<<meter<<" is neither the longest or shortest measurement."<<'\n';
break;
case'i':
cout<<var1<<inch<<" is neither the longest or shortest measurement."<<'\n';
break;
case'f':
cout<<var1<<foot<<" is neither the longest or shortest measurement."<<'\n';
break;
}
}
}
//after the break, this should be printed to screen
cout<<"Of a total of "<<e<<" entries. "<<small<<meter<<" is the smallest length."<<'\n';
cout<<"And "<<large<<meter<<" is the largest length. "<<total<<meter<<" is the total length."<<'\n';
return 0;
}
Apologies if the code is too long. I wasn't too sure what you would need. I have checked numerous posts and websites and tried different break codes but to no avail. I am stuck.
Maybe I am missing something glaring but the proper way to break a while loop is to make the conditional fail. Breaks are for FOR loops since they can be a non conditional loop. Instead of breaking out of the while loop you simply need to make the variable
d ='q'
Where ever you want to break out of the while. Note that the breaks are still valid to break out of a switch statement so if you need that then keep those breaks there.
sorry for any typos or if I missed a glaring issue, I am mobile and may have missed something
The first break statement will never be executed, because the 'if' condition is always false. All of the other break statements break from the switch statement, but not the while loop, so the loop will keep looping forever.
If I understand you correctly, I think you should change the 'false' to 'true' in the first 'if' condition. That being said, the code might overall have a bad design, but you mentioned you are a beginner, so I suggest you also learn how to optimize your code and write efficiently. Good luck.
Thank you for the help. Solved the problem by activating the break with my counter.
while(true)
{
if(e==d)
break;
When e reaches d value. The code breaks and outputs the information I want.
Its not how I wanted it to work but as stated. I think its poor programming.
thanks for your help guys, appreciated.

Program Crashes when I try to compare two strings in c++?

int removeContact(Contact *newPtr, int runningTotal)
{
//define variables
string remove;
int next;
//prompt user for name they wish to remove
cout << "Enter the name you would like to delete (Last name first): ";
cin.ignore();
getline(cin, remove);
for (int t=0; t<=runningTotal; t++)
{
if (remove.compare(newPtr[t].name) == 0)
{
//calls function moveArrayElements function
moveArrayElements(newPtr, runningTotal, t);
//decrement runningTotal
runningTotal--;
//prompt user contact was found
cout << "Contact was found and deleted!";
next=1;
}
}
if(next!=1)
{
cout<< "ERROR: Contact was not found!";
}
return runningTotal;
}
This function is apart of a larger c++ program that is designed to manage a persons contact information. This function is suppose to remove a contact.
The problem I'm have is with the if (remove.compare(newPtr[t].name) == 0) statement. When my program gets to this part of the code it will crash without giving any errors. I tried straight up comparing both the stings with == operator, but this still results in a crash of my program...
Also, what make this so strange is that this code works perfectly when the function is called while my program is running with the contact that I'm trying to remove not stored in a text file.
However, when I close my program, and load my contact information from the text file, my program will crash... I know that my program is reading the file into the proper string array because I have a print function, so I know that all of my contacts are being transferred into the proper structure arrays...
Any ideas on how I can fix this? Any help would be appreciated! Thanks
UPDATE: I took the suggestions in the comments and changed my for loop to
t<runningTotal;
However, when I do this my program doesn't crash, but it wont's compare the strings...
If runningTotal is the size of your array, then the range of valid elements is [0, runningTotal). In the below code, you're looping up to runningTotal inclusive, when there isn't a valid Contact object there:
for (int t=0; t<=runningTotal; t++)
{
if (remove.compare(newPtr[t].name) == 0)
Therefore when you go and dereference newPtr[t], for t = runningTotal and then try and get the name element, you'll be causing undefined behaviour and may cause a crash.
Try changing t<=runningTotal to t < runningTotal to see if the problem goes away.
Also, is there a reason why you're using arrays as opposed to an std::vector?
i guess the for statement should be:
for (int t=0; t<runningTotal; t++)

cannot figure out why stack works but not queue to check if a given word is a palindrome

I use stack and queue to check if a given word is a palindrome. The I can push a new character into stack but i cannot push more than one character into queue. I cannot see where is my mistake in the code. Any help will be appreciated. Below is the code in C++ using Dev-C++. Thanks for your time!
#include <iostream>
#include <stack>
#include <queue>
#include <string>
using namespace std;
void push_char()
{
string givenword; int sizeword, countchar;
string letter;
stack<string> stackword; string stawo1;
queue<string> queueword; string quewo1;
cout<<"enter the word to test "<<endl;
getline(cin,givenword);
string str (givenword);
sizeword=str.size();
cout<<" the word given "<<givenword<<" size of word= "<<sizeword <<endl;
countchar=0;
bool pali=true;
while ((countchar<sizeword))
{
stackword.push(str.substr(countchar,1));
queueword.push(str.substr(countchar,1));
cout<<" stack letter= "<<stackword.top()<<" queue letter= "<<queueword.front()<<endl;
countchar++;
if(stackword.top()==queueword.front())
cout<<"same letter found !"<<endl;
else
pali=false;
if (pali==false)
cout<<"not a palindrome"<<endl;
else
cout<<"palindrome!"<<endl;
}
}
int main()
{
push_char();
}
FYI, you can use str[countchar] instead of str.substr(countchar,
a few points:
1) Your code is fine, your algorithm is not. Grab a piece of paper and step through what you're doing.
2) I see what you're trying to do... something like this following untested code, right?
for(int i=0; i<sizeword; ++i) {
stackword.push(str[i]);
queueword.push(str[i]);
}
pali = true;
for(int i=0; i<sizeword; ++i) {
if(stackword.top() != queueword.front()) {
pali = false;
break;
}
stackword.pop();
queueword.pop();
}
There are better ways to find a palindrome... but that isn't the question you asked.
In this line:
if(stackword.top()==queueword.front())
Is where your error is. When you push into a queue, you push at the end of it. The front will not change. So to you it appears that there is only one thing in it.
When you push onto a stack, it pushes on top of the existing stack.
you have two options here. Number one is what aleph_null suggests - double pass where you add the characters into the containers in the first pass and compare them in the second pass. Second option is to compare them the way you do but looking at the opposite ends of the word. You don't actually need any containers for this but with the minimal changes your while loop the code should look like this:
while ((countchar<sizeword))
{
stackword.push(str.substr(countchar,1));
queueword.push(str.substr(sizeword - 1 - countchar,1)); // adding from the back
cout<<" stack letter= "<<stackword.top();
cout<<" queue letter= "<<queueword.back()<<endl; // .back() not .front()
countchar++;
if(stackword.top()==queueword.back()) // again, looking at the last added char
cout<<"same letter found !"<<endl;
else
pali=false;
// as Joe McGrath pointed out this should probably be outside the loop...
if (pali==false)
cout<<"not a palindrome"<<endl;
else
cout<<"palindrome!"<<endl;
}
Hope that helps.
Roman