12

I would like to create arrays like this:

string users[1][3];

users["CIRK"]["age"] = "20";
users["CIRK"]["country"] = "USA";
users["CIRK"]["city"] = "New York";

But I get this error:

index.cpp: In function 'int main()':
index.cpp:34: error: invalid types 'std::string [1][3][const char [5]]' for array subscript
index.cpp:35: error: invalid types 'std::string [1][3][const char [5]]' for array subscript
index.cpp:36: error: invalid types 'std::string [1][3][const char [5]]' for array subscript

Is it possible to create arrays like these in C++? In PHP, and Javascript they are very basic so I'm a bit surprised , how can I do it here?

Adam Halasz
  • 57,421
  • 66
  • 149
  • 213

4 Answers4

21

Array can only indexed by integers. If you want to index by chars, you need std::map or std::unordered_map in C++11. std::unordered_map is actually a hash table implementation. On the other hand std::map is red-black tree. So choose whatever fits your need.

std::unordered_map<std::string, std::unordered_map<std::string, std::string>> users;

users["CIRK"]["age"] = "20";
users["CIRK"]["country"] = "USA";
users["CIRK"]["city"] = "New York";
Mu Qiao
  • 6,941
  • 1
  • 31
  • 34
20

The data structure you are looking for is sometimes called an "associative array". In C++ it is implemented as std::map.

std::map<std::string, std::map<std::string, std::string> > users;

users["CIRK"]["age"] = "20";
users["CIRK"]["country"] = "USA";
users["CIRK"]["city"] = "New York";

You don't need to specify the dimensions, as a map will grow whenever a new item is inserted.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
4

PHP and Javascript are not strongly typed, in C++ you would want to create a structure describing your user rather than relying on arbitrary strings as keys:

struct User {
  size_t _age;
  std::string _city;
  std::string _country;
};

Then, you can indeed create an index to reference those users by name (you may also want to store the said name in the user). The two containers to do so are std::map and std::unordered_map, in general.

std::map<std::string, User> users;
User& user = users["CIRK"];
user._age = 20;
user._country = "USA";
user._city = "New York";

Note that I cached the look-up in the array by creating a reference (and that the object is automatically created if not already present).

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
2

No, unfortunately this is not possible with C++. You have to use mapping types like std::map or something similar to achieve what you are trying.

You could try using something like that:

#include <map>
#include <string>

...
std::map<std::string, std::map<std::string, std::string> >  users;
users["CIRK"]["age"] = "20";
users["CIRK"]["country"] = "USA";
users["CIRK"]["city"] = "New York";
Constantinius
  • 34,183
  • 8
  • 77
  • 85
  • Please don't encourage the use of `using namespace std;`. http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-a-bad-practice-in-c – Robᵩ Aug 30 '11 at 13:16
  • 3
    There is nothing wrong with using namespace std. It is in fact what makes namespaces manageable. There are places where you shouldn't use it, for example in header files to be included in more than one place, but in ordinary code it's not only acceptable but a good thing to use it. – jcoder Aug 30 '11 at 13:42