LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Set variable with value of another (https://www.linuxquestions.org/questions/programming-9/set-variable-with-value-of-another-269556/)

Ephracis 12-23-2004 08:50 AM

Set variable with value of another
 
I have a program that looks through a file that is in the format
Code:

option some value
My program reads through it and I have made it put the "option" into one variable and "some value" into another. Now I need to set a variable with the name "option" to "some value".

This:
Code:

char *option = "something";
char *value = "myvalue";

should become this:
Code:

char *something = "myvalue";
Any ideas?

bm17 12-23-2004 09:13 AM

You can not create a new C variable after the program has been compiled. That would be dynamic run-time name-binding, which C does not do. It sounds like you want to create an association between the string "option" and the string "some value". Most people do this by creating a lookup table. You can create a structure which contains two char* and maintain either a linked list or static table of pointers to those structures. You may then scan that table later on to do a lookup.

Or did I miss the question completely?

Ephracis 12-23-2004 09:57 AM

Hm. Ok so I can't create new variables at run-time. Say that I don't create new variables at runtime but that I have a list of all variables in a structure or something. Then when reading the file and finding a new "option" I would compare it with the structure. If I find a variable with the name that is the same as the "option" (in my example it is "something") I will change that variable into the value that comes after the option in the file. If the option is not found in the structure it will return an error about a invalid option in the file.

I need to have the option as a variable with the value of "value" in the file. Cause I will later use a variable called "option" in the program.

Now, the thing I need to know now is how to compare to see if the "option" is a variable inside a structure.

Code:

#include <stdio.h>
       
struct options {
        int option1;
        int option2;
        int anotherone;
        int thelastone;
};             
       
void read_file_function(options&);
       
int main() {
        // default options here
        options config = {3,15,230,1};
       
        /* ... */ 
         
        read_file_function(config);
        printf("OPTION\t\t\tVALUE\n");
        printf("option1:\t\t%i\n", config.option1);
        printf("option2:\t\t%i\n", config.option2);
        printf("anotherone:\t\t%i\n", config.anotherone);
        printf("thelastone:\t\t%i\n", config.thelastone);
               
        return 0;
}
               
void read_file_function(options &config) {
               
        char option[32];
        int value;
               
        /*
        the file is:
        option1 32
        option2 64
        badvalue 310
        */
         
        /* read from file here... */
        while (slabadish) {
       
                // reads line 1:
                option = "option1";
                value = 32;
       
                /* compare if value of option is in structure */
       
                /* if yes: */
                config.option1 = value;
       
                /* if no (line 3) */
                printf("error: bad value\n");
                exit(1);
        }
}

The bold line is the hard line. How can I compare the value of "option" with the names of the members in the structure?

bm17 12-23-2004 10:26 AM

The point of having a structure is to associate an option name with an option value, not to aggregate all of the option values. Perl is well suited for this problem. If you want to use C then it's going to be more complicated as you will have to manually manage all of the resource allocation yourself.

Perhaps the best approach is this:

Have a bunch of global variables that point to default values.

char* option_geography = "northern";
char* option_style = "reticulated";
char* option_species = "chipmonk";

then in your main loop you can read in the first word of the line and compare it (using strcmp) with the strings "geography", "reticulated", and "species". If, say, the word is "geography" then you need to allocate space to store the rest of the line and set option_geography to point at it.

If you want to get more sophisticated than that then you need to get a basic book on C and read what it says about to parsing tokens and lookup tables.

bm17 12-23-2004 10:45 AM

I saw in another thread that you are using c++ for this. That changes everything. Forget about char*. It is terrible for what you are doing. char* is good for buffer manipulation but absolutely sucks for strings, especially if you don't understand about dynamic memory allocation. Use the std::string class instead. Then you can store those string pairs in a std::map container. Your C++ book should have lots of information about this.

> I need to have the option as a variable with the value of "value" in the file. Cause I will later use a variable called "option" in the program.

I really think you are confusing the program with the data that the program operates on. C++ doesn't work that way. If you must use C/C++ then try to think of this as creating an association between two strings rather than adding a new variable to your program.

Ephracis 12-23-2004 11:01 AM

Yeah I study C++ at my school (moving very slow though) but I have been skipping ahead and read a pretty old (from 1995) book on basic C++.

I have been using the string-class before.

I know a little about how memory is being allocated since the book covers some of that and I have been reading about how to create/prevent a buffer overflow (which assumes knowledge about the memory stack and how memory is allocated). I have also looked at some assembler-code which (afaik) works alot with the memory.

I am sorry if using the wrong "terms" but I don't speak english so much so I have some problems with it. :P

Anyway the thing is for example I will let the program listen to a certain port by opening a socket. I later used the port as the second argument (./server 3010) and then converted it to a int and used it. Now I am trying to make an easy-looking configure-file that will define the port instead.

And I was hoping that I could use the format as I wrote before (it would maby be easier to use #define, but I am not afraid of trying complicated stuff). So lets say that I have two lines in the conf-file like this:
Code:

# give me a port
port 3010

From here I have made my program ignore the #-comment and seperate "port" and "3010", then putting them into two different variables (or how should I put it? :P).
Code:

if (!strcmp(option, "port"))
    ...
else if (!strcmp(option, "logfile"))
    ...
else
    invalid option

Of course I could use a "if" to check whether the name is "port" or "logfile" if I have only those two able to be set in the conf-file and then use "else" to show that the option was not a valide one.

But if I would have 50 different valid names of the option-part (port, logfile, logformat, alertlog, banfile, greeting, names, etc, etc) the if-part would be enormous, in-efficient and not very dynamical.

How should this be solved and please keep the english pretty simple so I won't have to buy a dictionary (those online suck).

bm17 12-23-2004 11:21 AM

Use s tructure like this:

struct {
char* name;
char* value;
};

then create an array of these structures and initialize their default values. Then when you read in a keyword you can loop through the array and compare the keyword to the name field in each struct, setting the value field if you find a match.

I'm not up to writing an example program for you. There should be something like it in your C book, or else you can find a piece of open source code that does something similar.

deiussum 12-25-2004 10:34 AM

Here's an example of how you could use a std::map class to do what I think you want:

Code:

#include <map>
#include <iostream>

typedef std::map<std::string, std::string> PropertyMap;

int main()
{
    PropertyMap oMap;

    // Assign a value to the "port" property
    oMap["port"] = "3600";

    // Check to see if there is a property in the map
    if (oMap.find("port") != oMap.end())
    {
        // Do something
    }

    // Get the value for a property to use for whatever
    std::cout << oMap["port"] << std::endl;
 
}



All times are GMT -5. The time now is 09:14 AM.