0

Say I have a text file "data.txt" and I created a struct:

struct newperson {
    string hair_colour;
    int age;
}

"data.txt" contains this info:

Sandy
brown
23

How can I create a Newperson struct and set its name to "Sandy" so that it would be the same as writing:

newperson Sandy;

It would probably use the getline function, but I'm lost as to how to implement it... in my inexperienced coding mind I would imagine it would be something like

ifstream file;
string line;
getline(file, line);
Newperson line;

Obviously this is really bad written and there's probably a million things wrong with writing like that.

  • 1
    I am not sure why you would want to do such a thing, but you cannot unless you have another program modify your source code before you compile it.........which I am pretty sure you don't want to do..... – DarthRubik Mar 16 '18 at 23:06
  • You can't. Your struct should include person_name or first_name, last_name as members. – Dave S Mar 16 '18 at 23:08
  • So different objects of the same type of struct don't have different names? So you would normally distinguish between them by giving another element such as "string name;"? – substrate098 Mar 16 '18 at 23:19
  • 1
    That's not the reason that you can't do this. When your code is compiled, variable names get swapped out for memory addresses, and you can't do anything with them at runtime. Their only purpose is to tell the compiler which is which. You probably want to use an `std::map` to map a string to a person. Also, it's probably a good idea to name your struct `Person` instead of `Newperson` since that name might be used in things other than creating a new object. – BessieTheCookie Mar 16 '18 at 23:30
  • "different objects of the same type of struct don't have different names?" Yes they do. Often the first would have the name FooStructs[0], the next name would be FooStructs[1], and so on, as in a "std::vector FooStructs;" – 2785528 Mar 17 '18 at 02:51

1 Answers1

1

You can't make variables at runtime without delving into really weird voodoo that operates outside the bounds of legal C++. It's not worth doing it. And even if you could, the variable names are early casualties while compiling. That variable file isn't called file anymore. It's probably something like stackpointer + 32 by the time the compiler and linker are through with it. So the idea of dynamically loading a variable name at runtime just isn't going to work.

But you can make a variable that maps the name of a person to an instance of your structure. The C++ standard library contains a couple such mapping classes, for example, std::map.

An example of using std::map for your case could look like:

std::ifstream file;
std::map<std::string, newperson> people;
std::string name;
std::string hair_colour;
int age;
if (getline(file, name) && 
    getline(file, haircolor) && 
    file >> age)// note: I left a boobytrap here
{ // only add the person if we got a name, a hair colour and an age
    people[name].hair_colour = hair_colour; // creates a newperson for name and sets
                                            // the hair_colour
    people[name].age= age;  // looks up name, finds the newperson and sets their age.
                            // warning: This can be a little slow. Easy, but slow.
}

Hint on boobytrap: Why does std::getline() skip input after a formatted extraction?

Later when you want to look up Sandy's age,

people["Sandy"].age

is all you need. But watch out, if Sandy is NOT in the the people map, the map will create and default-construct a new entry for Sandy. If you aren't certain Sandy is in the map, use the find method instead.

user4581301
  • 29,019
  • 5
  • 26
  • 45