tripleX - cin.clear(), cin.ignore(), while using pointers and structs

I’m taking an intro cs course in c++ at uni and we were learning about structs and pointers, so I’d thought of trying to make tripleX using what I’ve learned instead of directly following the tutorial. I made this function which takes four pointers to the values of the code’s products, sums, and the users guess’s products and sums and compare them.

bool CheckGuess(int *a, int *b, int *c, int *d, bool &complete)
{
    bool check = ((*a == *b)&&(*c == *d));
    std::cin.clear();
    std::cin.ignore(); 
    if (check == complete)
    {
        std::cout << "Wrong! The hacker is one step closer to collecting your intel.\n";
        return false;
    }
    else
    {
        std::cout << "You finally did it!\n";
        complete = true;
        return complete;
    }
}

It mostly works except that if the user inputs characters and words, my code prints out the line that results from a wrong guess several times:

There are three numbers in the code.
The digits of the code add up to 22
The digits multiply to 378
f  a aaa  <--- (my input)
Wrong! The hacker is one step closer to collecting your intel.
Wrong! The hacker is one step closer to collecting your intel.
Wrong! The hacker is one step closer to collecting your intel.
Wrong! The hacker is one step closer to collecting your intel.
Wrong! The hacker is one step closer to collecting your intel.

How can I get this to only print once, no matter what the user inputs?

Edit:

Here is my entire code. I changed the variable names to make it easier to read, but I may have messed something else up because now I get these errors:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\istream(484): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\istream(478): note: while compiling class template member function 'std::basic_istream<char,std::char_traits<char>> &std::basic_istream<char,std::char_traits<char>>::ignore(std::streamsize,int)'
tripleX.cpp(93): note: see reference to function template instantiation 'std::basic_istream<char,std::char_traits<char>> &std::basic_istream<char,std::char_traits<char>>::ignore(std::streamsize,int)' being compiled
tripleX.cpp(83): note: see reference to class template instantiation 'std::basic_istream<char,std::char_traits<char>>' being compiled
#include <iostream>

struct Passcode
{
    int A;
    int B; 
    int C;
};

void PrintIntro(int level);
bool CheckGuess(int *pGuessSum, int *pCodeSum, int *pGuessProd, int *pCodeProd, bool &complete);
bool GameStart();
void StoreGuess(Passcode *GuessDigits, int *pGuessProd, int *pGuessSum);

int main()
{
    int LevelDifficulty = 1;
    int const MaxDifficulty = 10;

    while (LevelDifficulty <= MaxDifficulty)
    {
        PrintIntro(LevelDifficulty);
        GameStart();
        ++LevelDifficulty;
    }

    return 0;
}


//Functions
void PrintIntro(int level)
{
    if (level == 1)
    {
        std::cout << "\n\nCrime is on the high. Hacking has never been easier than before.\n";
        std::cout << "With numerous hackers aiming to gain access to the secret government database, \n";
        std::cout << "You must quickly enter the correct code, or else risk leaking valuable intel: \n";
    }
    else
    {
        std::cout << "\n\nBUT WAIT! \n Your computer is now infected with more malware! \n";
        std::cout << "This hacker's malware looks tougher than before. Quickly enter the correct code! \n";
    }
    
}

bool GameStart()
{
    bool bLevelComplete = false;    
    
    //Declare 3 number code
    Passcode Code1 = {7 , 6, 9}; 

    //Print sum and product to terminal
    int CodeSum = Code1.A + Code1.B + Code1.C;
    int CodeProduct = Code1.A * Code1.B * Code1.C;
    int *pCS = &CodeSum;
    int *pCP = &CodeProduct;

    std::cout << "\nThere are three numbers in the code.";
    std::cout << "\nThe digits of the code add up to " << CodeSum;
    std::cout << "\nThe digits multiply to " << CodeProduct << "\n";
    
    //Create Guess Variables
    Passcode Guess;
    Passcode *pGuess = &Guess;
    int GuessSum, GuessProduct;
    int *pGS = &GuessSum;
    int *pGP = &GuessProduct;
    
    while (bLevelComplete == false)
        {
        StoreGuess(pGuess, pGS, pGP);
        CheckGuess(pGS, pCS, pGP, pCP, bLevelComplete);
        }
    return bLevelComplete;
}


void StoreGuess(Passcode *GuessDigits, int *pGuessProd, int *pGuessSum)
{
    std::cin >> (*GuessDigits).A >> (*GuessDigits).B >> (*GuessDigits).C;

    *pGuessSum = (*GuessDigits).A + (*GuessDigits).B + (*GuessDigits).C;
    *pGuessProd = (*GuessDigits).A * (*GuessDigits).B * (*GuessDigits).C;
}

bool CheckGuess(int *pGuessSum, int *pCodeSum, int *pGuessProd, int *pCodeProd, bool &complete)
{
    bool check = ((*pGuessSum == *pCodeSum)&&(*pGuessProd == *pCodeProd));
    std::cin.clear();
    std::cin.ignore();
   
    if (check == complete)
        {
        std::cout << "Wrong! The hacker is one step closer to collecting your intel.\n";
        return false;
        }
        else
        {
        std::cout << "You finally did it!\n";
        complete = true;
        return complete;
        }
}

Would you be able to provide the rest of your code to see how the CheckGuess function is being called?

I would also recommend renaming your parameters in your function to something more meaningful like “CodeSum” and “CodeProduct”, something like that so it is easier for someone else to know exactly what the function is doing. It would also be helpful to update your code snippet to the code format using the </> button in the editor on the top so it is a bit easier to read.

Seems like a lot of nitpicking from my end but it just makes it easier for everyone to understand your problem and work together to solve the issue :slight_smile:

I’ve edited your post to have correct formatting. Please do that in the future.

Also have the same questions as @Spectral_Knight as well as are you only using pointers and references to solidify your understanding?

Sorry for the unorganized post @DanM @Spectral_Knight. I included by entire code and changed the variables that were more ambiguous. I’m mostly trying to apply what I’ve been learning in my class with this tutorial to help solidify my understanding, but I also want to figure out these other bugs.

So there are a couple issues with this code.

  1. The one you described in the OP which is caused by not correctly checking for incorrect input. Given the following
    int a;
    std::cin >> a;
    
    If you were enter z then the extraction would fail as 'z' is not an int so std::cin's failbit would be set and will no longer attempt to extract characters until that is dealt with ('z' will still rermain in std::cin's buffer.)
  2. You are passing pGS to the argument expecting the product and pGP to the argument expecting the sum. This is were good names help a great deal.
  3. If your class was selling this as C++ then sorry but that’s not the case, this is C. You would not use out parameters or pointers at all for this code.
    For example these functions
    void StoreGuess(Passcode* GuessDigits, int* pGuessProd, int* pGuessSum);
    bool CheckGuess(int* pGuessSum, int* pCodeSum, int* pGuessProd, int* pCodeProd, bool& complete);
    
    Would look more like this in C++
    Passcode GetGuess();
    bool CheckGuess(Passcode Guess, Passcode Answer);
    

For the solution for the first problem you need to validate your input and clear std::cin of the failbit and discard its contents.

std::cin.clear(); //clear failbit
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard std::cin's entire contents.

Thanks for your explanations. My code now works and I can continue with the tutorial. As for the class, its currently trying to teach about memory by using the C++ language as the medium. So even though there are better ways to write the code for this game, I’m currently using this tutorial as extra practice to help improve my understanding. But again, thanks for the help!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.