0

G'day everyone!

I'm fairly new to C++, so bear with me if this is painfully obvious.

I'm trying to get a user to guess a string, which is just a vector containing random capital letters. That random letters part works great, however I can't figure out how to get my program to actually compare user input to the generated string in question. I decided to try a very simple program that would do only this and customize it to fit my main program, but I hit a bit of a bump. I need my program to print out that the user has guessed "x" amount of letters correctly (which I realize doesn't actually feature in this code, but that's because I just couldn't figure out how to do that)

#include <iostream>
#include <string>
#include <sstream>

int main(){
    std::string name,name2;
    int finish = 1;
    std::cout << "name?\n";
    std::cin >> name;
    std::cout << "enter name 2\n";

    while(finish != 0){
        std::cin >> name2;
        for (int i = 0; i != name.length())
        {

            if (name2[i] == name[i])
            {
                std::cout << "Correct!\n";
                finish = 0;
            }
            else{
                std::cout << "wrong\n";
            }
        }
    std::cout << "name is " << name;
}
return 0;
}

The particular code is something I just quickly put together in order to test it a bit before putting it into my main program, so it looks a bit messy and shabby. My problem is that this will print out "Correct!" a name.length() amount of times, which I don't want, but I do need it to actually display something like "Correct, X letters right" only once per guess.

My thinking is that the program checks each letter in name2 to that same corresponding letter position in the original name1 , and store (somewhere) that a letter has been guessed correctly, but after hours of Google-Foo, I just can't figure this one out.

EDIT: To clarify, I mean that my code will return "correct" the x amount of times for every correct string, and only then will it print out a "wrong".

Any help would be greatly appreciated!

Edited by luke_8: Clarification

2
Contributors
4
Replies
73
Views
1 Week
Discussion Span
Last Post by David W
2

Firstly, you may like to note that you mentioned using a vector of characters, but your code uses C++ strings, which is probably what you really meant to say?

Also, you need to lean to break up your program into 'jobs' ... and each job can be called by coding a function to do that specific job, then calling the function to execute that job at the appropriate place in the logic flow of your program.

Using descriptive function names, will help to self-document the logic flow of your program.

The following example may help you to see this:

// compareStrings.cpp //  // 2017-10-07 //

#include <iostream>
#include <sstream>
#include <string>
#include <cctype>

bool match( const std::string& a, const std::string& b, unsigned numChars )
{
    if( a.size() >= numChars && b.size() >= numChars )
    {
        for( unsigned i = 0; i < numChars; ++ i )
        {
            if( a[i] != b[i] ) return false;
        }
        // if reach here ...
        return true;
    }
    // if reach here ...
    std::cout << "Either '" << a << "'and/or '"
              << b << "' had less than " << numChars << " characters, so ...\n";
    return false;
}

std::string takeInString( const std::string& msg )
{
    std::cout << msg;
    std::string line;
    getline( std::cin, line );
    return line;
}

char takeInChr( const std::string& msg )
{
    std::string reply = takeInString( msg );
    if( reply.size() )
        return reply[0];
    // else ...
    return 0;
}

bool more( const std::string& text )
{
    if( tolower( takeInChr( "More " + text +
                 "(y/n) ? " ) ) == 'n' )
        return false;
    // else ...
    return true;
}

unsigned getNumToCheck()
{
    while( true )
    {
        std::string numStr = takeInString( "Enter number of characters to compare: " );
        std::istringstream iss( numStr ); // construct iss from numStr //
        int tmp;
        iss >> tmp;
        if( tmp > 0 ) return tmp;
        // else //
        std::cout << "Only postive integers are valid input here.\n";
    }
}

int main()
{
    do
    {
        std::string one = takeInString( "Enter 1st string to compare: " );
        std::string two = takeInString( "Enter 2nd string to compare: " );
        unsigned numToCheck  = getNumToCheck();
        if( match( one, two, numToCheck ) )
            std::cout << "Match occured for first " << numToCheck << " characters.\n";
        else
            std::cout << "NO match for first " << numToCheck << " characters.\n";
    }
    while( more( "lines to compare " ) );
}

Edited by David W

Votes + Comments
Call your things by names that make sense is always a good idea.
0

Hi David, thanks for the reply.

My main program involves actual vectors, I just tried making a smaller program that would actually do a comparison between user input and something else. Could you explain why you use unsigned type in several places? So far I haven't seen this be used in any of my programs while learning, I assume that it defaults to an int type, but I'm not too sure.

Edited by luke_8

0

Declaring a number with unsigned type is the same as declaring it with unsigned int type.

And note that the method
.size()
returns an unsigned int type.

So ...
when comparing numbers, we need to compare values with the same type.

We can safely assume here that the number of char’s you wish to check to be the same is a positive number ... yes?

If you need to use vectors of char ... just copy all the characters in each input string to a vector of type char ...

then your match function would compare two vectors of type char

Edited by David W

0

If you need use a C++ vector of char, (instead of C++ strings), you might like to try something like this:

// compareMyStrings.cpp //  // 2017-10-09 //

#include <iostream>
#include <vector>
#include <cstdlib> // re. atoi //
#include <cctype> // re. tolower //

typedef std::vector< char > MyString; // define MyString as a vector of type char elements //

// definition of overloaded operator << for MyString objects //
std::ostream& operator << ( std::ostream& os, const MyString& myStr )
{
    for( unsigned i = 0; i < myStr.size(); ++ i ) os << myStr[i];
    return os;
}

void readLine( std::istream& is, MyString& line )
{
    char ch;
    while( is.get( ch ) && ch != '\n' )
        line.push_back( ch );
}

bool match( const MyString& a, const MyString& b, unsigned numChars )
{
    if( a.size() >= numChars && b.size() >= numChars )
    {
        for( unsigned i = 0; i < numChars; ++ i )
        {
            if( a[i] != b[i] )
                return false;
        }
        // if reach here ...
        return true;
    }
    // if reach here ...
    std::cout << "Either '" << a << "'and/or '"
              << b << "' had less than " << numChars << " characters, so ...\n";
    return false;
}

MyString takeInString( const char* msg )
{
    std::cout << msg;
    MyString line;
    readLine( std::cin, line );
    return line;
}

char takeInChr( const char* msg )
{
    MyString reply = takeInString( msg );
    if( reply.size() )
        return reply[0];
    // else ...
    return 0;
}

bool more( const char* text )
{
    std::cout << "More " << text << " (y/n)? ";
    if( tolower( takeInChr( "" ) == 'n' ) )
        return false;
    // else ...
    return true;
}

unsigned takeInNumToCheck()
{
    while( true )
    {
        MyString numStr = takeInString( "Enter number of characters to compare: " );
        numStr.push_back( '\0' ); // 0 terminate //
        int tmp = atoi( (char*) &numStr[0] );
        if( tmp > 0 )
            return tmp;
        // else //
        std::cout << "Only postive integers are valid input here.\n";
    }
}

int main()
{
    do
    {
        MyString one = takeInString( "Enter 1st string to compare: " );
        MyString two = takeInString( "Enter 2nd string to compare: " );
        unsigned numToCheck  = takeInNumToCheck();
        if( match( one, two, numToCheck ) )
            std::cout << "Match occured for first " << numToCheck << " characters.\n";
        else
            std::cout << "NO match for first " << numToCheck << " characters.\n";
    }
    while( more( "lines to compare" ) );
}
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.