Assume I have Variable called "Volume", for example. I now have a file with Settings in it. Every Settings looks like this: ":
I now go through this file from top to bottom, and I want the program to store the Setting in a Variable with an equal Name.
e.G. if there is "Volume: 76", I want the program to write "76" into the Variable "Volume". How can I make the program to get the right Variable just by the string? Is this even possible?
There is no code yet, since I haven't started working on it yet. I was making thoughts about it.
You can't use variables directly, since the name must be existent at compile time, but reading a file is runtime.
You can use std::map though. Each settings will be a key, and the value will be read in.
std::map<std::string, std::string> settings;
settings["volume"] = "76";
But, the values ("76" in this case) will be strings as well. You can not use differing types directly.
I think, its possible with type erasure, but thats really advanced (and iam not fluent with it!).
Related
I'd like to be able to write some Lua code like this:
y=x+1
and be able to get the names of all variables (x and y in this case) so that I can read from/write to them in the calling C++ program. The problem is that x is uninitialized, so this chunk will not execute and therefore neither variable will appear in the globals table. My current work-around is to have the user explicitly declare that they want to initialize x externally (as well as how to initialize it), then I pre-pend the Lua script with an appropriate declaration for x, so that the final script looks like this:
x= /*some value calculated outside of the Lua script*/
y=x+1
Although this works, I'd really like to have a way to automatically list all uninitialized variables in the Lua code and present them to the user, instead of the user having to remember to explicitly declare them. A function that parses the Lua code without executing it would probably be what I want. I've tried the function luaL_loadstring, but x and y don't show up in the globals table.
Since this is a bit vague, I'll give an actual use case. My C++ code basically performs optimizations on functions, such as finding a root or a maximum. I want the user to be able to define custom functions (in the form of Lua scripts), which in general will have one or more inputs and one or more outputs. The user will define which parameters the optimizer should operate on. For example, the user may want to find the minimum of y=x^2. The way I'd like it to work is that the user writes a Lua script consisting of nothing more than y=x^2, and then tells the optimizer to vary x in order to minimize y. On each iteration of the optimizer, the current guess for x would be automatically pasted into the user script, which is then executed, and then the value of y is pulled from the Lua state to be fed back to the optimizer. This is how I have it working now, however it's a bit clumsy from a UX perspective because the user has to manually declare that x is a Lua variable. This gets tedious when there are many variables that require manual declaration. It would be much better if I could automatically scan the script and show the user a list of their undeclared variables so they could then use drag-and-drop and other GUI sugar to do the manual declaration.
Lua isn't meant to work like that. Lua/C interop is intended to be collaborative; it's not supposed to be that C can do whatever it wants.
Using your example, if you have a Lua script that is supposed to take a value from C and return that value + 1, then you spell that in Lua like this:
local x = ... --Get the first parameter to the chunk.
return x + 1 --Adds 1 to the value and returns it.
You compile this string into a Lua chunk and call it like a Lua function. You pass it the value you want to manipulate and get the return value from the Lua stack.
The idea is not that C code can just reach into a Lua script and shove data into it arbitrarily. The above chunk takes parameters from the user and provides return values to the user. That's typically how C interfaces with Lua.
Yes, you can write values to globals and have the Lua script read them, and write its "results" to globals that the external code reads. But this is not the most effective way to interact with scripts.
I'd really like to have a way to automatically list all uninitialized variables
There's no such thing in Lua as an "uninitialized variable". Not in the way that you mean.
Yes, there are globals. But whether that global has a value or not is not something the Lua script can control. A global is global after all; you can set a global variable from outside of the script (for example, see lua_setglobal). If you do, then a script that reads from it will read the value you set. But it doesn't know anything about that.
What you want is a static code analyzer/Lua linter. Take a look at Luacheck:
Luacheck is a static analyzer and a linter for Lua. Luacheck detects
various issues such as usage of undefined global variables, unused
variables, and values, accessing uninitialized variables, unreachable
code and more. Most aspects of checking are configurable: there are
options for defining custom project-related globals, for selecting set
of standard globals (version of Lua standard library), for filtering
warnings by type and name of related variables, etc. The options can
be used on the command line, put into a config or directly into
checked files as Lua comments.
There is also Lualint, and similar Lua linters for Atom, VSCode, or your fav IDE.
How can I give a name to a new variable or object using a string variable?
For example: After I compile the program, I enter the text "a_name", press [Enter] and then a vaiable or object with the name "a_name" gets declared. Another example: I enter the text "a_name", press [Enter] and then the variable called "a_name" shows it's value.
Are there any special Libraries for this, that have to be downloaded? Or are there ones that are included in the compilers files? If there are libraries that have to be downloaded, which are the easiest to understand and use? I'm using Visual C++, but with the Libraries Iostream, Math, String, e.t.c. copied from the DevC++ compiler.
You can't add "variables" to a program once it has been compiled. You
can get more or less the same effect, however, by using std::map, with
a string as the key type.
You will, of course, have to decide what type the new variable should
have, so you know what type to map it to. If there may be more than one type, something like boost::variant might be useful. (Note that unlike the set of names, the set of possible types must be completely defined at compile-time.)
As far as I know you can't. Variable names are set up on compile time and not on run time. C++ is not interpreted (like Perl, Python or JavaScript) thus it can't evaluate expressions on run time. C++ is ol' school.
I suggest you using arrays or C++ list/map classes to try to simulate this behavior.
You can't declare variables like that, what you may do however is use a map where the key of the map is the name of the variable you would like to refer to, and the value in the map having that key, is the value of the variable.
std::map<std::string, std::string> variables;
Obviously the value could be any type, and not just a string like I have used here, you can use double, int, bool or whatever suits your need, or if you need different types you might even use Boost variant as James Kanze suggested, or any other similar class.
Read more about maps here: http://www.sgi.com/tech/stl/Map.html and here: http://www.cplusplus.com/reference/stl/map/
You can use any kind of map, but a map using a sort of hashing to store the key might be your best bet. STL hash_map: http://www.sgi.com/tech/stl/hash_map.html
So basically what you are trying to do is include an interpreted language into your C++ program.
There are many languages that support being embedded into a C++ program Lua, JavaScript, Python to mention a few.
Is it possible to convert strings into variables(and vise versa) by doing something like:
makeVariable("int", "count");
or
string fruit;
cin >> fruit; // user inputs "apple"
makeVariable(fruit, "a green round object");
and then be able to just access it by doing something like:
cout << apple; //a green round object
Thanks in advance!
No, this is not possible. This sort of functionality is common in scripting languages like Ruby and Python, but C++ works very differently from those. In C++ we try to do as much of the program's work as we can at compile time. Sometimes we can do things at runtime, and even then good C++ programmers will find a way to do the work as early as compile time.
If you know you're going to create a variable then create it right away:
int count;
What you might not know ahead of time is the variable's value, so you can defer that for runtime:
std::cin >> count;
If you know you're going to need a collection of variables but not precisely how many of them then create a map or a vector:
std::vector<int> counts;
Remember that the name of a variable is nothing but a name — a way for you to refer to the variable later. In C++ it is not possible nor useful to postpone assigning the name of the variable at runtime. All that would do is make your code more complicated and your program slower.
You can use a map.
map<string, int> numbers;
numbers["count"] = 6;
cout << numbers["count"];
Beginning programmers ask this question regarding every language. There are a group of computer languages for which the answer to this question is "yes". These are dynamic, interactive languages, like BASIC, Lisp, Ruby, Python. But think about it: Variable names only exist in code, for the convenience of the programmer. It only makes sense to define a new variable while the program runs if there's a person to then subsequently type the name of the variable in new code. This is true for interactive language environment, and not true for compiled languages like C++ or Java. In C++, by the time the program runs, and the imaginary new variable would be created, there's no one around to type code that would use that new variable.
What you really want instead is the ability to associate a name with an object at runtime, so that code -- not people -- can use that name to find the object. As other people have already pointed out, the map feature of C++'s standard library gives you that ability.
You might want to look at C++ map.
No. C++ is statically typed, and this goes against that whole paradigm.
I have seen this type of functionality implemented before by storing variables in an stl map.
At least for the (vice versa) there is a possibility with the preprocessor statement stringify #. See this answer on how to convert a C++ variable name into an string.
well i guess u cannot make dynamics variables but u can use some function to write a new variable and its value in any external text file and access its value from that file where ever it is needed (u can also remove the dynamic variable by removing it from the text file.)
theory: variables are places in memory where we store data, identified by a name, we can store data in a text file if processor doesnot allow us to store it in registers, and we can access its value by searching its identity (name of variable) int the text file, our data will be next to it.
its just an idea, it should work but i guess it will be not very simple and ur program will have to pay in terms of speed.
So, I'm writting a CLI application in C++ which will accept a bunch of arguments.
The syntax is pretty typical, -tag arg1 arg2 -tag2 arg1 ...
Right now, I take the char** argv and parse them into an
std::map< std::string, std::list<**std::string** > > >
The key is the tag, and the list holds each token behind that tag but before the next one. I don't want to store my args as just std::strings; but I need to make it more interactive.
By interactive, I mean when a user types './myprog -help' a list of all available commands comes up with descriptions.
Currently, my class to facilitate this is:
class Argument
{
public:
Argument(std::string flag, std::string desc);
std::string getFlag();
std::string getDesc();
std:;list<std::string> > getArgs();
void setArgs(std::list<std::string> > args);
bool validSyntax()=0;
std::string getSyntaxErrorDesc()=0;
};
The std::map structure is in a class ProgramCommands which goes about handling the these Arguments.
Now that the problem description is over, my 4 questions are:
How do I give the rest of the program access to the data in ProgramCommands?
I Don't want to make a singleton, at all; and I'd prefer to not have to pass ProgramCommands as an arg to almost every function in the program.
Do you have better ideas about storing how I'm doing this?
How best can I add arguments to the program, without hardcoding them into the ProgramCommands, or main?
std::string only allows for 1 line descriptions, does anyone have an elegant solution to this besides using a list of strings or boost?
EDIT
I don't really want to use libraries because this is a school project (sniffing & interpreting packets). I could, if I wanted to, but I'd rather not.
Your choices on storing the command line arguments are either: Make them a global or pass them around to the functions that need them. Which way is best depends on the sorts of options you have.
If MANY places in your program need the options (for instance a 'verbose' option), then I'd just make the structure a global and get on with my life. It doesn't need to be a singleton (you'll still only have one of them, but that's OK).
If you only need the options at startup time (i.e. # of threads to start initially or port # to connect on), then you can keep the parsing local to 'main' and just pass the parameters needed to the appropriate functions.
I tend to just parse options with the venerable getopt library (yes, that's a leftover from C - and it works just fine) and I stuff the option info (flags, values) into a global structure or a series of global variables. I give usage instructions by having a function 'print_usage' that just prints out the basic usage info as a single block of text. I find it works, it's quick, it's simple, and it gets the job done.
I dont understand your objection to using a singleton to - this is the sort of thing they are made for. If you want them accessible to every object but not pass them as arguments or use a singlton - there are only a couple of tricks I can think of:
-put the parsed arguments them into shared memory and then read them from every function that needs them
-write the parsed arguments out to a binary file and then read them from every function that needs them
-global variables
None of these solutions are nearly as elegant as a singleton, are MUCH more labor intensive and are well... sort of silly compared to a singleton... why hamstring yourself?
In C++ is there any function that returns "true" when the variable is defined or false in vice versa. Something like this:
bool isDefined(string varName)
{
if (a variable called "varName" is defined)
return true;
else
return false;
}
C++ is not a dynamic language. Which means, that the answer is no. You know this at compile time, not runtime.
There is no such a thing in runtime as it doesn't make sense in a non-dynamic language as C++.
However you can use it inside a sizeof to test if it exists on compile time without side-effects.
(void)sizeof(variable);
That will stop compilation if var doesn't exist.
As already stated, the C++ runtime system does not support the querying of whether or not a variable is declared or not. In general a C++ binary doesn't contain information on variable symbols or their mappings to their location. Technically, this information would be available in a binary compiled with debugging information, and you could certainly query the debugging information to see if a variable name is present at a given location in code, but it would be a dirty hack at best (If you're curious to see what it might look at, I posted a terrible snippet # Call a function named in a string variable in C which calls a C function by a string using the DWARF debugging information. Doing something like this is not advised)
Microsoft has two extensions to C++ named: __if_exists and __if_not_exists. They can be useful in some cases, but they don't take string arguments.
If you really need such a functionality you can add all your variables to a set and then query that set for variable existance.
Already mentioned that C++ doesn't provide such facility.
On the other hand there are cases where the OS implement mechanisms close to isDefined(),
like the GetProcAddress Function, on Windows.
No. It's not like you have a runtime system around C++ which keeps remembers variables with names in some sort of table (meta data) and lets you access a variable through a dynamically generated string. If you want this, you have to build it yourself, for example using a std::map that maps strings to some objects.
Some compile-time mechanism would fit into the language. But I don't think that it would be any useful.
In order to achieve this first you need to implement a dynamic variable handling system, or at least find some on the internet. As previously mentioned the C++ is designed to be a native language so there are no built-in facilities to do this.
What I can suggest for the most easy solution to create a std::map with string keys storing global variables of interest with a boost::any, wxVariant or something similar, and store your variables in this map. You can make your life a bit easier with a little preprocessor directive to define a variables by their name, so you don't need to retype the name of the variable twice. Also, to make life easier I suggest to create a little inline function which access this variable map, and checks if the given string key is contained by the map.
There are implementation such a functionality in many places, the runtime property handling systems are available in different fashion, but if you need just this functionality I suggest to implement by yourself, because most of these solutions are quite general what you probably don't need.
You can make such function, but it wouldn't operate strings. You would have to send variable name. Such a function would try to add 0 to the variable. If it doesn't exists, an error would occur, so you might want to try to make exception handling with try...throw...catch . But because I'm on the phone, I don't know if this wouldn't throw an error anyways when trying to send non-existing variable to the function...