1

Task: You are given the noises made by different animals that you can hear in the dark, evaluate each noise to determine which animal it belongs to. Lions say 'Grr', Tigers say 'Rawr', Snakes say 'Ssss', and Birds say 'Chirp'.

Input Format: A string that represent the noises that you hear with a space between them.

Output Format: A string that includes each animal that you hear with a space after each one. (animals can repeat)

Sample Input: Rawr Chirp Ssss

Sample Output: Tiger Bird Snake

This is what I have tried:

#include <iostream>
#include <string>
using namespace std;
int main() {
    string noises[4] = {"Grr", "Rawr", "Ssss", "Chirp"};
    string animals[4] = {"Lion", "Tiger", "Snake", "Bird"};

    string sounds;
    getline(cin, sounds);

    string sounds_filtered[sounds.size() - 1];

    string word;

    for (string::size_type i = 0; i < sounds.size(); i++) {
        if (sounds[i] != ' ') {
            word = word + sounds[i];
        } else {
            for (int i = 0; i<sounds.size(); i++) {
                if (sounds_filtered[i] == "") {
                    sounds_filtered[i] = word;
                    break;
                }
            }
            word = "";
        }
    cout << sounds_filtered;
    }

    return 0;
}

I think I am halfway trough the challenge, but my problem is, sounds_filtered does not contain only the words but also what it seems like pointers?

I would appreciate it if you do not give me the answer but an explanation of what I am doing wrong and were to read about it, thank you

  • `sounds_filtered` is a string array, but you are not printing its items, you are printing the address of the array. Further, `sounds_filtered` is given `size` but you never set its contents. Check that `sounds[i] != ' '` is always `true` and `word` is never assigned to `sounds_filtered`. Thus, you never use `word` neither `noises`. Maybe this assignment was intended for arrays practice, but the problem would be easier to solve using a dictionary via `std::map`. – stateMachine Apr 03 '21 at 01:49

1 Answers1

1

There are a couple of issues with your approach.

  • Reading an entire line and trying to split it is more difficult than just reading each sound one at a time and outputting the animal. That also helps with the next issue since you don't need the array if you read word by word.
  • Variable length arrays, like string sounds_filtered[sounds.size() - 1]; are not standard C++ and will not work on all compilers. If you need something like this consider a std::vector instead.
  • cout << sounds_filtered; won't work, as you've noticed. You would need a loop to print each item in the array.
  • using namespace std; may save you a bit of typing and seem more convenient but it can lead to difficult to diagnose problems when you have a name conflict. You can read more about that here if you like: Why is "using namespace std;" considered bad practice?

Here is an example of reading each sound one at a time and outputting the animal. I used a std::map to simplify matching the sound to the animal. You could use parallel arrays for this as you do in your example but it does make looking things up more difficult. If you do stick with the arrays I'd advise putting the lookup in a function to make the main loop easier to read.

#include <iostream>
#include <string>
#include <map>

int main()
{
    // Map of noise -> animal
    std::map<std::string, std::string> noiseToAnimal =
    {
        { "Grr", "Lion"}, {"Rawr", "Tiger"}, {"Ssss", "Snake"}, {"Chirp", "Bird"}
    };

    std::string input;
    // Read one word at a time
    while (std::cin >> input)
    {
        // Find the noise in the map
        auto it = noiseToAnimal.find(input);
        // If the noise was found then assign the animal to the output string,
        // otherwise assign "Unknown"
        std::string output = it != noiseToAnimal.end() ? it->second : "Unknown";
        // Print the output followed by a space
        std::cout << output << ' ';
    }

    return 0;
}
Retired Ninja
  • 4,785
  • 3
  • 25
  • 35
  • Why are you using auto as a type?, couldn't it be string? –  Apr 03 '21 at 03:02
  • 1
    @SalvadorBG -- The `find` function returns an iterator, not a string. If you need convincing, remove the `auto` keyword and attempt to compile the program with the type you think should take its place. You will realize that it is `std::map::iterator`. So what's easier, typing all of that, or simply have the compiler help out and simply use `auto`? – PaulMcKenzie Apr 03 '21 at 03:42
  • @SalvadorBG Paul is right, I used `auto` because nobody likes typing out super long iterator types. I try to use it sparingly since it isn't always a huge savings and I feel like the actual type is more helpful to me when reading the code. – Retired Ninja Apr 03 '21 at 12:55