Array inputs

I would like to create an array that allows for me to collect a series of strings in combination with one another.

Asking the user to give their pet type (dog or cat) along with the name of their pet.to look something like this:

Dog Spot
Cat Fluffy
cat Mr. Pickles
dog Rover
etc.

And when done collecting enter Done to escape

Eventually to go back and speak with said pets:

for example:

user input:

Hello <insert pet name>!

expected output:

"Woof!" or "Meow!" depending on the animal.

I have nearly everything, what I am really looking for is a little guidance with the storing information in a vector, retrieving the information when needed, and some of the conditional arguments to better understand the structure and logic behind them.

I understand that this isn't complete and wont function like it should just yet, but her is my implementation code so far.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 #include "stdafx.h"

#include <iostream>
#include <vector>
#include "Dog.h"
#include "Cat.h"

int main()
{
    std::string petType, petName;

    std::vector< std::string > petSet;

    std::cout << "Enter your pet type Dog or Cat : ";
    std::cin >> petType;

    while (petType != "Dog" || petType != "dog" || petType != "Cat" || petType != "cat")
    {


        if (petType == "Dog" || petType == "dog")
        {
            std::cout << "What is your pet's name?: ";
            std::cin >> petName;

            


            Dog* dog = new Dog(petName);
            // need to move this to a condition, Speak when spoken to 
            dog->speak();

        }
        else if (petType == "Cat" || petType == "cat")
        {

            std::cout << "What is your pet's name?: ";
            std::cin >> petName;





            Cat* cat = new Cat(petName);
            // need to move this to a condition, Speak when spoken to 
            cat->speak();
        }
        else
        {
            std::cout << "I don't understand." << std::endl;
            std::cout << "Enter your pet type Dog or Cat : ";
            std::cin >> petType;
        }

    }

}


Thank you
I like to address problems by starting with the data.

Here you have pet names and pet types (dog, cat, etc.)
Each name is associated with a type.
Each type has something that they say.

So you need to map pet name to pet type, and you need to map pet type to what they say.

1
2
3
4
5
std::map<std::string, std::string> nameToType;  // maps name->type. Type must be lower case
std::map<std::string, std::string> typeToGreeting;  // maps pet type (lower case) to greeting

typeToGreeting["cat"] = "Meow";
typeToGreeting["dog"] = "Woof";


Now the program logic is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// read the pet names
while (true) {
    read type and name;
    convert type to lower case
    if (type == "done") break
    if (type isn't in typeToGreeting map) {
        tell user that isn't a known type of pet
    } else {
        nameToType[name] = type;
}

// Read the greetings
string hello, name;
while (cin >> hello >> name) {
    if (hello != "Hello") {
        cout << "how rude!\n";
    } else if (name isn't in nameToType) {
        cout << "I don't know that pet\n";
    } else {
        cout << typeToGreeting[nameToType[name]] << '\n';
    }
} 

I hate asking this explicitly because i'm trying to learn, and want to have that eureka moment when it clicks and I understand whats going on, but that doesn't seem to be happening. And I have been trying to find a mentor or mentors that can put up with what might seem like blatantly stupid questions. So far this community has been extremely fantastic at that.

So going over this problem, I have restarted and have decided to go with a similar method that you have suggested with two different Actions, instead of one big loop.

The first being, asking the user a simple input of the desired input a std::string in the form of <Dog|Cat Name>. Creating a list of "Pets".

1
2
3
4
5
6
// Where Pet is a base-class I have constructed for my derived-classes Dog and Cat
std::vector< Pet* > listOfPets;

std::string userCommand;

std::cout << "Enter the list of pet type and pet name in the form <Dog|Cat Name>. When you are finished enter <done> \n";


Wanting that list of pets stored in a std::vector<Pets*>

Having conditional loops while the user is inputting the list


something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//  1.) while the userCommand is not equal to done, continue to add to the list 
    while ( userCommand != "done" )
    {
        std::cin >> userCommand;

// 2.) essentially have to check for 3 possibilities "done", "Dog|Cat Name", 
//or "neither of the previous two options"
// first things first in the while loop stop if it is "done" 

        if ( userCommand != "done" )
        {
      //here is where I run into not understanding the function calls on std::string to check
      //for specific words (thinking of using .find() ? ) and how the proper syntax  
     //of the arguments should be. Parsing the information accordingly from std::cin?

//3.) Ultimately if userCommand is a Cat or Dog with a Name, then storing 
//the string in a vector to be later called upon when addressing them 
        }
    }


And the second Action after collecting the data from the user,
Utilizing the stored data to talk to specific pets on the list, having them respond in their "language" Woof or Meow

* not so much focusing on the second aspect of it right now though, that will come later

Any help or links to useful literature would is greatly appreciated.
One day I hope i can give back to this community too.


One thing that will make this easier is accepting that the loop condition comes in the middle of the loop. Something like this (untested):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
while (true) {
    std::cin >> userCommand;
    if (userCommand == "done") {
        break;
    } else if (userCommand == "dog") {
        std::cin >> petName;
        listOfPets.push_back(new Dog(petName);
    } else if (userCommand == "cat") {
        std::cin >> petName;
        listOfPets.push_back(new Cat(petName);
    } else {
        cout << userCommand << "isn't a type of pet. Please enter cat or dog\n";
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <string>
#include <cctype>
#include <memory>
#include <vector>

struct pet
{
    explicit pet( std::string its_name ) : name(its_name) {}

    virtual ~pet() = default ;
    void speak() const { std::cout << name << ": " << sound() << "!\n" ; }

    protected:
        virtual std::string sound() const = 0 ;
        const std::string name ;
};

struct dog : pet
{
    using pet::pet ;
    protected: virtual std::string sound() const override { return "woof" ; }
};

struct cat : pet
{
    using pet::pet ;
    protected:  std::string sound() const override { return "meow" ; }
};

std::string& to_lower( std::string& str )
{
    for( char& c : str ) c = std::tolower( (unsigned char)c ) ;
    return str ;
}

int main()
{
    std::vector< std::unique_ptr<pet> > my_pets ;

    std::string type;
    std::string name ;
    while( std::cout << "Enter your pet type and pet name: " &&
           std::cin >> type && to_lower(type) != "done" &&
           std::cin >> name )
    {
        if( type == "cat" ) my_pets.push_back( std::make_unique<cat>(name) ) ;
        else if( type == "dog" ) my_pets.push_back( std::make_unique<dog>(name) ) ;
        else std::cout << "unsupported pet type\n" ;
    }

    for( const auto& pet_ptr : my_pets ) pet_ptr->speak() ;
}
Topic archived. No new replies allowed.