C++ - evaluating an input string as an internal code variable - c++

Is there a way to take a string as an input argument to a c++ function and evaluate it as an internal argument e.g. the name of a structure or other variable?
For example (written in pseudo code)
int myFunction(string nameStructure){
nameStructure.field = 1234
}
The "take away" point is converting the input string as a variable within the code.
Mark

This type of question is often a symptom of a XY problem so consider other options first. That being said, there's no such default mechanism in C++ but there is a simple workaround I can think of - use a dictionary (std::map / std::unordered_map) to store all your objects:
std::map<std::string, MyAwesomeObject> objects;
...
int myFunction(std::string nameStructure)
{
objects[nameStructure].field = 1234
}

The names of local variables are just artifacts of the human-readable code and have no meaning in the compiled binary. Your int myIntVar's and char* myCharP's get turned into instructions like "four bytes starting at the location of the base pointer minus eight bytes, interpreted as a four-byte integer". They no longer have names as such.

If you export symbols from your binary, you can at runtime to look into export table according to your binary format and find the variable you want. But i bet you want something like access to local variable and that is not possible.
If you really need this funcionality, take a look at more dynamic interpreted languages as php
http://php.net/manual/en/language.variables.variable.php

Related

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.

How to put spaces in variable names?

I want to learn how to add spaces in variable names.
I know that a lot languages prevent me from doing this, but I believe that there is a trick to do this because I saw someone did it in MQL5
A MetaTrader Terminal allows to show a UI-Dialogue Panel for MMI-assisted setting values for input and extern variables declared in { Expert Advisor | Technical Indicator | Script } code, during a code-execution launch.
( Ref. a picture below ): .
If you really want to be evil you can sometimes use the left-to-right mark, U+200E which looks like a regular space but is generally not considered whitespace. Different languages and/or specific platforms may behave differently.
This trick seems to work in C# and apparently you can do similar things in ruby.
I tried this using g++ and luckily for everyone's sanity it is not allowed:
foo.cc:5:10: error: non-ASCII characters are not allowed outside of literals and identifiers
int a<U+200E> b = 3;
Please don't do this outside of pranks and April fool's day jokes.
In C++ you can't put spaces in variable names but you can get what you want using a std::map.
For example:
#include <map>
#include <string>
int main()
{
std::map<std::string, std::string> vars;
vars["Time Frame"] = "15 minutes";
vars["Indicator Period"] = "16";
// ... etc
}
The std::map is an associative container that maps one std::string onto another.
Depending on how you intend to use the map you may also want to consider using an std::unordered_map which should have higher performance but will not keep the keys sorted and may have a higher memory usage.
As much as I know, there isn't any option to add spaces to variables name.
The trouble with using spaces in names (whether filenames, variable names or something else) is that you need to have some other mechanism for determining what is part of this name and what is part of the next section of code. Your sample looks like a form, so that has it's own formatting and structure.
SQL does allow you to "quote" variable names with either [name with space] or with backticks `name with space`.
Most other languages do not allow spaces in variable names, because any whitedspace is considered a separator for different lexical unit [different name/word/variable]. There is no way you can change this, as it would alter the meaning of "normal code". Most languages do allow/use _ as a "space in names" character.
Of course, if you have "variables" that are your own construct, read from for example a database or file, you can use your own syntax, and use for example std::map<std::string, sometype> or std::unordered_map<std::string, sometype> to connect the string from your data to the corresponding value.
Spaces (white space) are used in C++ to isolate keywords and variable names, thus they cannot exist in a variable name or the compiler will treat the text as multiple identifiers.
Example - valid: static const unsigned int my_variable = 6U;
If there is a space between my and variable how does the compiler know which is the variable name? If there are two variables here, it doesn't make sense.
Also, as you can see, there may be more than one keyword in a statement.
I find a solution .In Mql5 , when you add a comment next to the variable name , it will appear instead of the variable name .
See this image : http://prntscr.com/79vaae

C++, need help with pointers created with strcat!

I need to append a number at the end of the word flare depending on how many I have. That part works great. My problem is when I go to print it to the screen. I would like the program to output the value of what (Camera::Table[Id]->sensor->flare1) sensor is pointing at, in this case, flare one. If the program were to continue it would output the value pointing at flare2, flare3, flare4,... until the limit is reached.
What I get as the output is the following:
lens_pos1=¨Camera::Table[Id]->sensor->flare1¨
lens_pos2=¨Camera::Table[Id]->sensor->flare2¨ .......
How can I output the value of flare1 instead of pasting the string?
What I want is the following:
lens_pos1=¨10.3¨ lens_pos2=¨12.4¨.....
Where the values 10.3, 12.4 would be those of flare1 and flare2 respectively taken from a seperate C file.
for(int i = 1; i <= nbflares; i++)
{
char integer_string[32];
sprintf(integer_string, "%d", i);
char flare[100] = "Camera::Table[Id]->sensor->flare";
strcat(flare,integer_string);
fprintf(yyout, "lens_pos%d=\"%s\" ",i,flare);
}
You can't access a variable like that in C/C++. You have to redesign the "sensor" structure to contain an array instead of individual flares, and access the array by index: Camera::Table[Id]->sensor->flare[1], Camera::Table[Id]->sensor->flare[2], etc.
That can't be done in C++. Some interpreted languages might allow such things because the text of the source code still exists while the program is running. But in C++, when you compile a program all the names of classes and variables and such are essentially lost. When it gets to the point of a running executable, the actual machine instructions are just working with offsets and memory addresses.
So you need re-design how the data is stored.
Is there a way to access them without the use of arrays?
Technically, yes. But only by using a more complicated scheme that would involve a more complicated data structure (such as a linked list or map).
Why would you want to avoid arrays anyway? Right now you have a series of variables of the same type that you want to distinguish by the number are the end of their names. And an array is a series of variables of the same type that are distinguished by their index in the array. It's pretty much a perfect match.
For example, if you had a flares array, then you could simply do something like:
for(int i = 0; i < nbflares; i++)
{
fprintf(yyout, "lens_pos%d=\"%f\" ", i, Camera::Table[Id]->sensor->flares[i]);
}

Named parameter string formatting in C++

I'm wondering if there is a library like Boost Format, but which supports named parameters rather than positional ones. This is a common idiom in e.g. Python, where you have a context to format strings with that may or may not use all available arguments, e.g.
mouse_state = {}
mouse_state['button'] = 0
mouse_state['x'] = 50
mouse_state['y'] = 30
#...
"You clicked %(button)s at %(x)d,%(y)d." % mouse_state
"Targeting %(x)d, %(y)d." % mouse_state
Are there any libraries that offer the functionality of those last two lines? I would expect it to offer a API something like:
PrintFMap(string format, map<string, string> args);
In Googling I have found many libraries offering variations of positional parameters, but none that support named ones. Ideally the library has few dependencies so I can drop it easily into my code. C++ won't be quite as idiomatic for collecting named arguments, but probably someone out there has thought more about it than me.
Performance is important, in particular I'd like to keep memory allocations down (always tricky in C++), since this may be run on devices without virtual memory. But having even a slow one to start from will probably be faster than writing it from scratch myself.
The fmt library supports named arguments:
print("You clicked {button} at {x},{y}.",
arg("button", "b1"), arg("x", 50), arg("y", 30));
And as a syntactic sugar you can even (ab)use user-defined literals to pass arguments:
print("You clicked {button} at {x},{y}.",
"button"_a="b1", "x"_a=50, "y"_a=30);
For brevity the namespace fmt is omitted in the above examples.
Disclaimer: I'm the author of this library.
I've always been critic with C++ I/O (especially formatting) because in my opinion is a step backward in respect to C. Formats needs to be dynamic, and makes perfect sense for example to load them from an external resource as a file or a parameter.
I've never tried before however to actually implement an alternative and your question made me making an attempt investing some weekend hours on this idea.
Sure the problem was more complex than I thought (for example just the integer formatting routine is 200+ lines), but I think that this approach (dynamic format strings) is more usable.
You can download my experiment from this link (it's just a .h file) and a test program from this link (test is probably not the correct term, I used it just to see if I was able to compile).
The following is an example
#include "format.h"
#include <iostream>
using format::FormatString;
using format::FormatDict;
int main()
{
std::cout << FormatString("The answer is %{x}") % FormatDict()("x", 42);
return 0;
}
It is different from boost.format approach because uses named parameters and because
the format string and format dictionary are meant to be built separately (and for
example passed around). Also I think that formatting options should be part of the
string (like printf) and not in the code.
FormatDict uses a trick for keeping the syntax reasonable:
FormatDict fd;
fd("x", 12)
("y", 3.141592654)
("z", "A string");
FormatString is instead just parsed from a const std::string& (I decided to preparse format strings but a slower but probably acceptable approach would be just passing the string and reparsing it each time).
The formatting can be extended for user defined types by specializing a conversion function template; for example
struct P2d
{
int x, y;
P2d(int x, int y)
: x(x), y(y)
{
}
};
namespace format {
template<>
std::string toString<P2d>(const P2d& p, const std::string& parms)
{
return FormatString("P2d(%{x}; %{y})") % FormatDict()
("x", p.x)
("y", p.y);
}
}
after that a P2d instance can be simply placed in a formatting dictionary.
Also it's possible to pass parameters to a formatting function by placing them between % and {.
For now I only implemented an integer formatting specialization that supports
Fixed size with left/right/center alignment
Custom filling char
Generic base (2-36), lower or uppercase
Digit separator (with both custom char and count)
Overflow char
Sign display
I've also added some shortcuts for common cases, for example
"%08x{hexdata}"
is an hex number with 8 digits padded with '0's.
"%026/2,8:{bindata}"
is a 24-bit binary number (as required by "/2") with digit separator ":" every 8 bits (as required by ",8:").
Note that the code is just an idea, and for example for now I just prevented copies when probably it's reasonable to allow storing both format strings and dictionaries (for dictionaries it's however important to give the ability to avoid copying an object just because it needs to be added to a FormatDict, and while IMO this is possible it's also something that raises non-trivial problems about lifetimes).
UPDATE
I've made a few changes to the initial approach:
Format strings can now be copied
Formatting for custom types is done using template classes instead of functions (this allows partial specialization)
I've added a formatter for sequences (two iterators). Syntax is still crude.
I've created a github project for it, with boost licensing.
The answer appears to be, no, there is not a C++ library that does this, and C++ programmers apparently do not even see the need for one, based on the comments I have received. I will have to write my own yet again.
Well I'll add my own answer as well, not that I know (or have coded) such a library, but to answer to the "keep the memory allocation down" bit.
As always I can envision some kind of speed / memory trade-off.
On the one hand, you can parse "Just In Time":
class Formater:
def __init__(self, format): self._string = format
def compute(self):
for k,v in context:
while self.__contains(k):
left, variable, right = self.__extract(k)
self._string = left + self.__replace(variable, v) + right
This way you don't keep a "parsed" structure at hand, and hopefully most of the time you'll just insert the new data in place (unlike Python, C++ strings are not immutable).
However it's far from being efficient...
On the other hand, you can build a fully constructed tree representing the parsed format. You will have several classes like: Constant, String, Integer, Real, etc... and probably some subclasses / decorators as well for the formatting itself.
I think however than the most efficient approach would be to have some kind of a mix of the two.
explode the format string into a list of Constant, Variable
index the variables in another structure (a hash table with open-addressing would do nicely, or something akin to Loki::AssocVector).
There you are: you're done with only 2 dynamically allocated arrays (basically). If you want to allow a same key to be repeated multiple times, simply use a std::vector<size_t> as a value of the index: good implementations should not allocate any memory dynamically for small sized vectors (VC++ 2010 doesn't for less than 16 bytes worth of data).
When evaluating the context itself, look up the instances. You then parse the formatter "just in time", check it agaisnt the current type of the value with which to replace it, and process the format.
Pros and cons:
- Just In Time: you scan the string again and again
- One Parse: requires a lot of dedicated classes, possibly many allocations, but the format is validated on input. Like Boost it may be reused.
- Mix: more efficient, especially if you don't replace some values (allow some kind of "null" value), but delaying the parsing of the format delays the reporting of errors.
Personally I would go for the One Parse scheme, trying to keep the allocations down using boost::variant and the Strategy Pattern as much I could.
Given that Python it's self is written in C and that formatting is such a commonly used feature, you might be able (ignoring copy write issues) to rip the relevant code from the python interpreter and port it to use STL maps rather than Pythons native dicts.
I've writen a library for this puporse, check it out on GitHub.
Contributions are wellcome.

Initializing a char array in C. Which way is better?

The following are the two ways of initializing a char array:
char charArray1[] = "foo";
char charArray2[] = {'f','o','o','\0'};
If both are equivalent, one would expect everyone to use the first option above (since it requires fewer key strokes). But I've seen code where the author takes the pain to always use the second method.
My guess is that in the first case the string "foo" is stored in the data segment and copied into the array at runtime, whereas in the second case the characters are stored in the code segment and copied into the array at runtime. And for some reason, the author is allergic to having anything in the data segment.
Edit: Assume the arrays are declared local to a function.
Questions: Is my reasoning correct? Which is your preferred style and why?
What about another possibility:
char charArray3[] = {102, 111, 111, 0};
You shouldn't forget the C char type is a numeric type, it just happens the value is often used as a char code. But if I use an array for something not related to text at all, I would would definitely prefer initialize it with the above syntax than encode it to letters and put them between quotes.
If you don't want the terminal 0 you also have to use the second form or in C use:
char charArray3[3] = "foo";
It is a a C feature that nearly nobody knows, but if the compiler does not have room enough to hold the final 0 when initializing a charArray, it does not put it, but the code is legal. However this should be avoided because this feature has been removed from C++, and a C++ compiler would yield an error.
I checked the assembly code generated by gcc, and all the different forms are equivalent. The only difference is that it uses either .string or .byte pseudo instruction to declare data. But tha's just a readability issue and does not make a bit of difference in the resulting program.
I think the second method is used mostly in legacy code where compilers didn't support the first method. Both methods should store the data in the data segments. I prefer the first method due to readability. Also, I needed to patch a program once (can't remember which, it was a standard UNIX tool) to not use /etc (it was for an embedded system). I had a very hard time finding the correct place because they used the second method and my grep couldn't find "etc" anywhere :-)