C++ Using strings to access variables [duplicate] - c++

This question already has answers here:
Access variable value using string representing variable's name in C++ [duplicate]
(8 answers)
Closed 7 years ago.
Suppose I have a structure bbox containing 6 sets, where each set contains 4 vectors. I can add a vector element by using bbox.set1.vect1.push_back(foo). However, I'm reading data from a file and I'm looking for an elegant way to store the data in the vectors. Using a double for() loop with indices i (1 to 6) and k (1 to 4) I've tried the following (using string concatenation):
string test1 = "bbox.set";
string test2 = ".vect";
string fin = test1 + to_string(i) + test2 + to_string(k);
fin.push_back(val);
Though the code compiles fine, nothing seems to happen. Explicitly writing bbox.set1.vect1.push_back(foo) does work. Can this be done in such a way? In another topic I've read that C does not support changing/creating variable names during runtime, but here I simply try to access an existing variable.

No, C++ does not support this, since variable names are resolved at compile time, which means that by the time the program runs, the variable names themselves are meaningless. (In other words, the name bbox has in practice been replaced by a set of numbers representing the object called by that variable name.)
If you really need to something like this, you should consider using a container such as std::map, which you can use to map strings to objects. You can't access them like variables, though, but you can dynamically build strings to decide which object to get.

What you are looking for is some method of reflection, which C++ does not natively support. There is no way to do what you want directly.
Instead you will need to provide your own support.

Related

How do I prevent strings containing the word "yes" or "no" from printing out as true or false? [duplicate]

This question already has answers here:
How can I prevent SerializeJSON from changing Yes/No/True/False strings to boolean?
(7 answers)
Closed 6 years ago.
I'm currently setting a number of variables like so:
<cfset printPage = "YES">
Eventually, when I print these variables out, anything that I try to set to "YES" prints out as "true". Anything set to "NO", prints out as "false". I'm not opposed to using the YesNoFormat function. In fact I might end up using that function in this application, but in the mean time I would like to know if ColdFusion is actually storing the words "YES" and "NO" in memory, or if it is converting them to a boolean format behind the scenes.
If CF is storing my variables exactly the way that I declare them, how would I go about retrieving these variables as strings? If CF is changing the variables in some way, are there any special characters or keywords that I could use to force it to store the variables as strings?
Thank you to everyone that commented / answered. I did a little more experimenting and reading, and it seems that the serializeJSON function will automatically convert "Yes" to "true" and "No" to "false". I either need to deal with this problem in my javascript, or I can add a space in the affected properties to circumvent this behavior.
You already know how to display the boolean value as "yes" or "no" (using YesNoFormat()). I don't think there is a way to force ColdFusion to store a variable a certain way. It just doesn't support that. I guess you could call out the Java type directly by using JavaCast(). I just don't see why you would want to go through that extra work for something like this. You can certainly research that a bit more if you like. Here is a link to the document for JavaCast.
Have a look at this document regarding data types in ColdFusion. I will post some of the relevant points from that document here but please read that page for more information.
ColdFusion is often referred to as typeless because you do not assign types to variables and ColdFusion does not associate a type with the variable name. However, the data that a variable represents does have a type, and the data type affects how ColdFusion evaluates an expression or function argument. ColdFusion can automatically convert many data types into others when it evaluates expressions. For simple data, such as numbers and strings, the data type is unimportant until the variable is used in an expression or as a function argument.
ColdFusion variable data belongs to one of the following type categories:
Simple One value. Can use directly in ColdFusion expressions. Include numbers, strings, Boolean values, and date-time values.
Binary Raw data, such as the contents of a GIF file or an executable program file.
Complex A container for data. Generally represent more than one value. ColdFusion built-in complex data types include arrays, structures, queries, and XML document objects. You cannot use a complex variable, such as an array, directly in a ColdFusion expression, but you can use simple data type elements of a complex variable in an expression. For example, with a one-dimensional array of numbers called myArray, you cannot use the expression myArray * 5. However, you could use an expression myArray[3] * 5 to multiply the third element in the array by five.
Objects Complex constructs. Often encapsulate both data and functional operations.
It goes on to say this regarding Data Types:
Data type notes
Although ColdFusion variables do not have types, it is often convenient to use “variable type” as a shorthand for the type of data that the variable represents.
ColdFusion provides the following functions for identifying the data type of a variable:
IsArray
IsBinary
IsBoolean
IsImage
IsNumericDate
IsObject
IsPDFObject
IsQuery
IsSimpleValue
IsStruct
IsXmlDoc
ColdFusion also includes the following functions for determining whether a string can be represented as or converted to another data type:
IsDate
IsNumeric
IsXML
So in your code you could use something like IsBoolean(printPage) to check if it contains a boolean value. Of course that doesn't mean it is actually stored as a boolean but that ColdFusion can interpret it's value as a boolean.

(C++/ QT) Use a switch statement with strings by turning the strings into an int [duplicate]

This question already has answers here:
How to write a switch statement for strings in Qt?
(3 answers)
Closed 6 years ago.
At this website I found an interesting way to create a switch statement with strings. However, this seems really long and drawn out. I wanted to know if it's possible to turn a particular string into an integer that can be used in a switch statement.
So psuedo code would be something like this
QString str = "spinbox_1";
switch stoi( str )
case 1543:
//code here
case 2343:
//code here
case 3424:
//code here
As #Slava mentioned it is not easily possible. The solution provided by author in mentioned link is probably the most practtical solution. But if you for some reason really need to do it other way and convert string into decimal number, you can use hashing metod. Please refer to below cityhash which is widely used (obviously you can use any other hashing function).
https://github.com/google/cityhash
This may be duplicate of:
How can I hash a string to an int using c++?
Try to look at this solution:
https://github.com/Efrit/str_switch/blob/master/str_switch.h
Unfortunately the description of this solution is avaliable only in Russian (at least I can't find one in English). It is based on computing hash of the string in compile-time. The only limitation it has is it supports strings with 9 character maximum length.
If I ever find myself in a similar situation, I use a map to define a specific int from the given string.
For Example:
// The string you want to convert to an int
std::string myString = "stringTwo";
// The mapping that you set for string to int conversions
std::map<std::string, int> stringToInt = \
{{"stringOne" , 1},
{"stringTwo" , 2},
{"stringThree", 3}};
// Here, myInt is define as 2
int myInt = stringToInt[myString];
Now you could put myInt into a switch case.
No, it is not possible to map a string to an integer uniquely in general - there are simply more strings than integers. You may calculate hash which unlikely to collide for 2 different string and then compare them, but it is still possibility that 2 different strings have the same hash, so you have to compare that strings after you check their hashes. This is how std::unordered_set or std::unordered_map are implemented (aka hash_set and hash_map) so you can use them. But you would not use switch() statement.

C++ Assigning variables with 'compound names' using an external argument

I'm trying to read a .pdb file and hence I'm ending with a lot of variables in my code. In an effort to reduce them (and avoid Segmentation fault errors) I was wondering if I could assign array names in my code using an external argument.
The starting bit of my code foo.cpp looks like this-
/*All the relevant headers*/
using namespace std ;
int main(int argc, char *argv[])
{
ifstream input(argv[1],ios::out) ;
string first(argv[2]) ;
string second(argv[3]) ;
string "first"ATOM[1000] ;
string "second"ATOM[1000] ;
}
And I'm hoping that if I launch the program as ./foo.exe input C O, I want two arrays called CATOM and OATOM to be initialised.
If there is no second argument then the OATOM array should not get defined.
This would save me the trouble of having to make multiple arrays such as NATOM[1000], OATOM[1000] etc. since I can define them within the program.
Is this possible? For each 'O', 'C', 'N' etc there need to be about 8-10 long string arrays which is causing it to blow up.
I'm new to programming and I hope this question makes sense.
Thanks in advance!
I suggest creating a struct with array and a string variable containing the name of that array and then you just search the structs by name.
A more elegant solution is using std::map like #NathanOliver suggested. Runtime changes of variable names are not possible (or logical) within c++ as far as I know.
It is not possible to change or set variable names at run time.
However, map (also known as dictionary or associative array) is a data structure that allows you to associate key objects (such as a string) to value objects (such as an array) and it possibly fits your needs. There is an implementation of map in the standard library, that you can use.

C++ strings vs vector<char> [duplicate]

This question already has answers here:
What are differences between std::string and std::vector<char>?
(5 answers)
C++: char test[100] vs array<char, 100> vs string
(4 answers)
Closed 7 years ago.
It's known to everyone of us that we should prefer string class in C++ for all string applications due to the many special functions they perform & their ability to grow & reduce dynamically. What string is for characters, vector is for other data types & classes because it shows great performance.
However is there any situation where we would need to prefer vector<char> (which I see seldom) over string ?
I'd use vector<char> only if I explicitly intent to store an array of char values, which is not a string. E.g. if for some reason I'd collect all the characters used somewhere in a specific text, the result might be a vector<char>.
To be clear: it is all about expressing the intent.
To put it briefly: if you're storing text, then string, otherwise vector<char>.

C++ equivalent of Java Enum.valueOf() [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Is it possible to define enumalpha?
Is there any equivalent of Java Enum.valueOf(string) on C++?
There's no table of names generated by the compiler (unless you count debug information), but if you create one (or use e.g. doxygen which parses the source code and can output such lists in XML format) then you can use a dictionary of some type, such as std::map<string, int> to turn an identifier into its numeric value.
No, there isn't even the much simpler task of going the other way (enum to string), you'd need to write it yourself