0

Lets say I have a char pointer like this:

const char* myS = "John 25 Lost Angeles";

I want to parse this string and put it in a hashmap, so I can retrieve the person's age and city based on his name only. Example:

std::map<string, string> myMap;

john_info = myMap.find("John");

How can I do this to return all of John's info in an elegant way ? I come from a Java background and I really want to know how this is properly done in C++. That would also be cool if you can show me how to do this using a boost map (if it is easier that way). Thank you.

  • 2
    Use `std::stringstream`. FYU `std::map` is not a hashmap. – 273K Feb 01 '22 at 19:44
  • 1
    what did you try? how would you do it in Java? – OznOg Feb 01 '22 at 19:46
  • For a hash table, use `std::unordered_map`. That said, it looks like your question is about two things: parsing the string and storing the parsed string. I recommend removing the bit about hash maps and focussing the question on the parsing. I highly recommend making a `class` that aggregates the information and parsing the string into that object. Might be worth writing a [custom `operator >>` overload](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading). – user4581301 Feb 01 '22 at 19:57

1 Answers1

1

I'm going to show you one way to do it using Boost:

Live On Coliru

#include <map>
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;

using Name = std::string;
struct Details {
    unsigned age;
    std::string city;
};

using Map   = std::map<Name, Details>;
using Entry = Map::value_type;

BOOST_FUSION_ADAPT_STRUCT(Details, age, city)

int main() {
    Map persons;

    std::string_view myS = //
        "John 25 Lost Angeles\n"
        "Agnes 22 Minion Appolis";

    auto name    = x3::lexeme[+x3::graph];
    auto age     = x3::uint_;
    auto city    = x3::raw[*(x3::char_ - x3::eol)];
    auto details = x3::rule<struct details_, Details>{} = age >> city;
    auto line    = name >> details;
    auto grammar = x3::skip(x3::blank)[line % x3::eol];

    if (x3::parse(myS.begin(), myS.end(), grammar, persons)) {
        for (auto& [name, details] : persons)
            std::cout << name << " has age " << details.age << "\n";
        for (auto& [name, details] : persons)
            std::cout << name << " lives in " << details.city << "\n";
    }

    // lookup:
    std::cout << "John was " << persons.at("John").age << " years old at the time of writing\n";
}

Prints

Agnes has age 22
John has age 25
Agnes lives in Minion Appolis
John lives in Lost Angeles
John was 25 years old at the time of writing

To use a hash-map, just replace

using Map   = std::map<Name, Details>;

with

using Map   = std::unordered_map<Name, Details>;

Now the output will be in implementation-defined order.

CAVEAT

If this is home-work, please don't use this (kind of) approach. It will be very clear it was copy-pasted. Never use code you don't fully understand.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • In the interest of overkill, I think the better representation would be a `Person { name, age, city }` struct that has several indices: http://coliru.stacked-crooked.com/a/c456a9d2f8964e6c – sehe Feb 01 '22 at 21:30
  • Thanks man. This is not HW, but interview prepping. I appreciate it. – Saturnsbelt Feb 01 '22 at 21:34
  • 1
    I guess for interview prepping the same caveat heavily applies. But I'd be thrilled to see someone write this code on an interview :) – sehe Feb 01 '22 at 21:42
  • For interview purposes, I ***bet*** they expect you to write standard-library only solutions, so e.g. http://coliru.stacked-crooked.com/a/56fbd9c5e5eafbcd or http://coliru.stacked-crooked.com/a/86447e97201159d6 – sehe Feb 01 '22 at 22:07
  • What does line 14 do ? The friend keyword is used. What does that do ? – Saturnsbelt Feb 02 '22 at 00:07
  • @Saturnsbelt see here https://stackoverflow.com/a/382077/85371 (perhaps part 2 is https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading#:~:text=std%3A%3Aistream%26%20operator%3E%3E(std%3A%3Aistream%26%20is%2C%20T%26%20obj)) – sehe Feb 02 '22 at 00:19