Reading strings and integers from textile

Hi, I have a script that uses several variables. I first give all these variables a value. I then want the script to read a textfile and if it finds the variables replace the value set in the program with the value in the textfile.

The textile looks like this:
1
2
3
4
Variable1
10
Variable2
30


I was able to write a code that stores all values and variable names in the following variables:

VariableValue[]
VariableName[]

So in this case I will have

VariableName[0]=Variable1
VariableName[1]=Variable2
VariableValue[0]=10
VariableValue[1]=30

How can I now replace the variable Variable1 with 10?
closed account (48bpfSEw)
You need a temporary variable for replacing

int a=1;
int b=2;

replacing a with b :

int temp = a;
a = b;
b = temp;


do you know maps?

#include<map>

Map<string, int> map;

map["Variable1"] = 10;
map["Variable2"] = 20;
Hi, Thanks for helping out! I am not sure if you understand my problem.

Just to be clear. In the textfile the variable names can differ. So I need the script to read the variable name and value from the textfile and then assign the value to the variable with the name specificed in the textfile.

I am not familiar with maps and will look into that.

Basically I declare some variables and I want to be able to easily change a few without having to rebuild the executable every time.
Last edited on
Necip's suggestion to use a std::map is a good one. std::map is an associative container so you can reference entries in the map by name.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <map>
#include <string>
#include <fstream>
using namespace std;

map<string, int> varmap;

//  Read a collection of variable name/value pairs from a file
void load_map (const char * filename)
{   ifstream    ifs (filename);
    string      varname;
    int         value;
    
    while (ifs >> varname)
    {   ifs >> value;
        varmap[varname] = value;
    }
}


The downside is that to reference a variable you have to do so my name.
 
  if (varmap["variable1"] == 10)


If performance is an issue, you could copy the map entries to explicit variables:
1
2
3
  int variable1;
...
  variable1 = varmap["variable1"];

Last edited on
Thanks!

It now works. To deal with the downside you explained I use this command:

 
if (varmap["variable1"] != NULL){ variable1 = varmap["variable1"]; }


It is a bit dirty though because now I have to retype this piece of code for all variable names (About 20) and it does not work if the value in the textfile is 0.

How can I fix it so that an input of 0 will also be accepted but not filling it in at all won't?
Last edited on
How can I fix it so that an input of 0 will also be accepted but not filling it in at all won't?

Note that the map::[] operator always returns a reference, so it will never return a null.
If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value.
http://www.cplusplus.com/reference/map/map/operator[]/

For that, you want to use map::find.
http://www.cplusplus.com/reference/map/map/find

1
2
3
4
5
6
7
8
9
10
void load_variable (const char * varname, int & val)
{   map<string,int>::iterator    iter;

    iter = varmap.find (varname);
    if (iter == varmap.end())
        return;  // not found 
    val = iter->second;  // assign value
}

    load_variable ("variable1", variable1);


It is a bit dirty though because now I have to retype this piece of code for all variable names (About 20)

I don't often recommend the use of #define , but this is a case where #define's token pasting can be useful.
http://www.cplusplus.com/doc/tutorial/preprocessor/

1
2
3
4
  #define LOADVAR(var)  load_variable(#var,var)  // pass argument as quoted string and as reference
...
  int variable1 = 0;  // Default value in case not found in text file
  LOADVAR(variable1);

Last edited on
Thanks for helping! Everything is working now :)
Topic archived. No new replies allowed.