Using a user variable to access a member of struct? C++ [duplicate] - c++

This question already has answers here:
How to use a string as a variable name in C++? [duplicate]
(2 answers)
Closed 7 years ago.
Say I have the following struct:
struct movie {
char movie_name[32];
int rating;
int release_year;
char location;
}
Normally, I would access the rating by saying "movie.rating".
For this project, I have to take input from a text file. I will read a variable such as "movie_name" or "rating" or "release_year" from the file, and given that variable, I have to access the corresponding element of the struct.
Ex: if the input file reads "movie_name", then I want to access movie.movie_name. How do I do this without making 4 if statements? Is there another way?
if(input == "movie_name")
movie.movie_name = ...
else if(input == "rating")
movie.rating = ...
The real struct I'm working with has 20+ members, so I am trying to find a more efficient way to write this code.
Thanks in advance!

In C/C++ it is not possible to access variable using a string; so there is no way to do this using the struct you provide. A map might be an alternative:
map<string, int>
but then each variable will map on the same type of variable (int in this case)... You should look to the related questions: How to use a string as a variable name in C++? and Convert string to variable name or variable type

What you are looking for is called reflection. unfortunately, it is not supported in C++. One solution to your problem which is not an optimal one of course is to implement your struct as map of pair<key,value> as follow:
struct movie {
std::map<string,ValueType> foo;
}
However, the problem is the ValueType. If boost is available, Then this could be a better solution:
struct movie {
std::map<string,boost::variant<typeX, typeY>> foo;
}

Related

Why do we use functions that return a data structure in C++? [duplicate]

This question already has answers here:
Which is more efficient: Return a value vs. Pass by reference?
(7 answers)
Closed 2 years ago.
I have been learning C++ and came across a function, but the return type was a vector.
Here is the code:
vector<Name> inputNames() {
ifstream fin("names.txt");
string word;
vector<Name> namelist;
while (!fin.eof()) {
Name name;
fin >> name.first_name;
fin >> name.last_name;
namelist.push_back(name);
}
return namelist;
}
name is part of a struct defined as:
struct Name {
string first_name;
string last_name;
bool operator<(const Name& d) const {
return last_name > d.last_name;
}
void display() {
cout << first_name << " " << last_name << endl;
}
};
What is the purpose of using vector< Name>inputName()? What is it doing?
And why can I just not create a void function and pass a vector through it?
I.e.:
void input(vector<Name>&v){
ifstream fin("names.txt");
string word;
while (!fin.eof()) {
Name name;
fin >> name.first_name;
fin >> name.last_name;
v.push_back(name);
}
}
Your question is basically: Do I return by value or do I use an output argument?
The general consensus in the community is to return by value, especially from C++17 on with guaranteed copy elision. Although, I also recommend it C++11 onwards. If you use an older version, please upgrade.
We consider the first snippet more readable and understandable and even more performant.
From a callers perspective:
std::vector<Name> names = inputNames();
It's clear that inputNames returns you some values without changing the existing state of the program, assuming you don't use global variables (which you actually do with cin).
The second code would be called the following way:
std::vector<Name> names;
// Other code
inputNames(names);
This raises a lot of questions:
does inputNames use the names as input or does it extend it?
if there are values in names, what does the function do with it?
does the function have a return value to indicate success?
It used to be good practice when computers were slow and compilers had troubles optimizing, though, at this point, don't use it for output arguments.
When do you use the last style: if you want an in-out argument. In this case, if you intend to append, the vector already had data, and that actually makes sense.
This basically mirrors the mathematical definition of a function as...
...a relation that associates an input to a single output.
While you could write void functions that modify their parameters, this has disadvantages:
Expression of intent. Consider a function taking multiple parameters. Which ones are input, which ones are output?
Clarity of purpose. A function modifying multiple values at once is usually (not always) attempting to do too many things at once. Focussing on one return value per function helps with keeping your program logic under control.
RAII. You can't use a void function to initialize a variable, meaning you would have to declare that variable first (initialized to some "default" value), then initialize it to the desired value.
There are languages that work without return values, using "out parameters" instead. You can do it this way in C++ as well. But all in all, using return values as the one output of a function helps the structure of your program.
vector<Name> is the return value of the method. It will create a new object with a vector of the structs.
Your implementation is called "call by reference". It will pass the pointer to an existing vector. As a example, with the call by the reference implementation, you could call input(vector<Name>&v) multiple times and your preexisting vector will have multiple times the content. If you would to it with the vector return value, it would always create a new object with only one iteration of data.

How can I use a string as the name of an integer? C++ [duplicate]

This question already has answers here:
How to use a string as a variable name in C++? [duplicate]
(2 answers)
Closed 4 years ago.
Hello guys i´m new to programming and i ran into a problem. I have a String and I use the lenght of the String to create variables according to the lenght of the string. I want to use a string("usagetxt_whl_str") as the name of my integer. Every time the loop runs it should create a new variable with a diffrent name. for example: 1_var, 2_var and so on
QString usagetxt = "example"
int usagetxt_len = usagetxt.length();
int usagetxt_whl = 0;
QString usagetxt_whl_str = QString::number(usagetxt_whl);
while (usagetxt_whl != usagetxt_len){
usagetxt_whl = usagetxt_whl + 1;
**here im trying to create my var**int usagetxt_whl_str + "_var" = 0;* }
How can I get this to work?
Is it even possible?
C++ is a compiled language. So you cannot create a variable name at run-time.
However there are several alternatives that can address the need of having a dynamic number of "variables" (in reality of values). The first one is to use a vector. Here you create a vector that contains usagetxt_len integers :
std::vector<int> myvars(usagetxt_len);
You can then access each of these integers with the traditional indexing operator:
myvars[i] = i;
As indexing is numeric (starting with 0 of course), you can easily process them in loops.
Another approach to dynamic "variables" is based on strings. You can then define a name in a string, and access the variable:
std::map<string, int> myvalues;
You could then access specific values associated to strings:
myvalues["4_var"]=0;
myvalues["5_var"]=myvalues["4_var"]+3;
As you are new to programming, I think that the vectors will do the job. It's just a change in the way you think on a group of values.

creating a const value based on user input [duplicate]

This question already has answers here:
C++ : Creating an array with a size entered by the user
(3 answers)
Closed 3 years ago.
I am trying to get a user input and set it as the PUZZLESIZE which is used by int peg and row but am getting the expression must have a constant value.
How would I go about getting a user input and setting it as a global const that struct Board will recognize?
int a;
const int PIECE = a;
const int PUZZLESIZE = ((PUZZLESIZE *(PUZZLESIZE+1)) /2);
typedef struct Board {
int *row[PUZZLESIZE];
int peg[PIECE];
int lastmove;
struct Board *prevBoard;
int prow;
int pcol;
} Board;
int main()
{
scanf("%d",a);
}
Thanks for any help in advanced
Re-setting the value of a const variable at runtime is not possible.
You just defined PIECE as a const (constant variable):
const int PIECE = a;
So, you cannot change the value of PIECE after starting the program.
You have to rethink a little about how your program will work. In addition since you are using C++ you may consider the use of the language features and libraries so that you can follow best practices as recommended by #Joren.
You have 2 options:
Option 1 : Make PuzzleSize your largest supported puzzle.
If you do this all you need to do is validate the user input against this size.
In addition you don't have to fiddle with memory allocation.
Simple solution
Potentially can have large segments of unused memory
Option 2: Make row a double pointer and use new to allocate your rows.
typedef struct Board
{
int **row; // int *row[PUZZLESIZE];
....
}
once the user sets the input you can validate the input and do this
int main()
{
scanf("%d",a);
row = new int*[a]; }
Don't forget to take a look at your C++ book and read up on const, multidimensional arrays ,and new.
Good Luck!

C++: defining a struct inside another struct? [duplicate]

This question already has answers here:
Why would one use nested classes in C++?
(6 answers)
Closed 7 years ago.
so I've been playing around with C++. I was trying to figure out if it's possible to define a structure in the definition of another structure. And here's my code.
#include <iostream>
using namespace std;
int main(){
struct structure1{
int integer1;
struct structure2{
int integer2;
}struct2;
}struct1;
structure1 *s1 = &struct1;
s1->integer1 = 50;
cout<<"STRUCTURE ONE'S INTEGER: "<<s1->integer1<<endl;
cout<<"STRUCTURE ONE'S STRUCTURE2.integer2: "<<s1->struct2.integer2;
}
OUTPUT:
$ ./a.out
STRUCTURE ONE'S INTEGER: 50
STRUCTURE ONE'S STRUCTURE2.integer2: 0
From what I saw in the output it had seemed to be working. But I just don't understand why or how it worked. Is it good practice? Is there any application to this?
Thanks!
But I just don't understand why or how it worked.
Why wouldn't it work? It's perfectly legal C++.
Is it good practice?
Depends on how it's used.
Is there any application to this?
Definitely. For example when you only need structure2 inside structure1 and nowhere else. It's good to make its scope as small as possible.
For more information: Why would one use nested classes in C++?

Accessing a array of Structs using pointer notation

I am trying to learn C++ on my own and was trying out this. I have a struct one of whose member is an array of another structs. I have a question about alternative notation.
The structs that I have defined are
struct employeeRecordT {
string name;
string title;
string ssnum;
double salary;
int withholding;
};
struct payrollT {
int num;
employeeRecordT *array;
} payroll;
I am allotting memory to payroll using the following construct
payroll.array = new employeeRecordT[payroll.num];
where payroll.num is indicating the number of elements in the array. I can access the element name of the employeeRecordT by using the array notation e.g.
payroll.array[i].title
I wanted to know how to access this using the pointer notation, I have tried
payroll.(array+i)->name = "Vikas";
and I get the following error message from g++
toy.cc:30:13: error: expected unqualified-id before '(' token
toy.cc:30:14: error: 'array' was not declared in this scope
I am trying to understand what I should be using and why? Could you guys help explain.
Thanks in advance.
Regards,
Vikas
(payroll.array+i)->name = "Vikas";
array is a member of payroll, so when you were doing payroll.(array+i), the bracket notation (i.e. "do this first") was trying to use a variable array, and not the one within the scope of payroll.
Of course, using C++, the better solution is Neils. Use a std::vector instead of your own dynamically allocated storage if possible.
If it hurts, don't do it. Use a std::vector of your structures instead.