Set int that has the same name as content in a String

Hi!

Is there a way to set and int that has the same name as the content in a String?
For example I have an int called numberBuffer and a String called stringBuffer, and the content in stringBuffer is numberBuffer. Can I use the String to set the int to a value?
I'm asking because I want to use a for loop which uses a String array which contains the names of ints I want to set values to.

Regards,
Christian

Sure, but you have to code the string compares to find the correct int. The compiler replaces the names you choose with the actual memory address, so nothing is going to happen magically, if that is what you are hinting at.

Paul

Of course, nothing happens magically when coding. I can already find the String which has the same name as the int. I think I only need to know how to use it to set the int.

It's not clear what you want to do. An example would be a good idea.

If you imagine a user sending a word via Serial (let's assume "myBigNumber") and if when you wrote the program you created a variable called myBigNumber and if you want something to happen to that variable because the word "myBigNumber" has been sent then you are in for a big disappointment because there is no such thing in the code uploaded to the Arduino as a variable known within the code as myBigNumber

You could write a program that checks the content of the received message - something like this pseudo code

if (strcmp(messageReceived, "myBigNumber") 
  myBigNumber += 1;
}

But that could get very tedious.

...R

chrstrvs:
Of course, nothing happens magically when coding. I can already find the String which has the same name as the int. I think I only need to know how to use it to set the int.

I guess the number is also in a string following the name? Then use the string to int conversion to make an int and move the new int into to numberBuffer.

Paul

Robin2:
You could write a program that checks the content of the received message - something like this pseudo code

if (strcmp(messageReceived, "myBigNumber") 

myBigNumber += 1;
}

That would be a lot more likely to work as:

if (strcmp(messageReceived, "myBigNumber")  == 0)
    myBigNumber += 1;
}

Regards,
Ray L.

It sounds like you are trying to do something like this:

int numberBuffer = 0 ;
String stringBuffer = "numberBuffer" ; 

magicFunction( stringBuffer , 27 ) ;  // extracts the text name of variable to be updated, locates the variable, and updates it with the supplied parameter.

// now numberBuffer has value 27

Some interpreted languages ( vbscript, perl, javascript etc. etc. ) have an EVAL or similar statement which allows you to do this. Not, unfortunately, C/C++.

6v6gt:
It sounds like you are trying to do something like this:

int numberBuffer = 0 ;

String stringBuffer = "numberBuffer" ;

magicFunction( stringBuffer , 27 ) ;  // extracts the text name of variable to be updated, locates the variable, and updates it with the supplied parameter.

// now numberBuffer has value 27




Some interpreted languages ( vbscript, perl, javascript etc. etc. ) have an EVAL or similar statement which allows you to do this. Not, unfortunately, C/C++.

That's exactly what I want to do. Sorry for being unclear.
That's unfortunate, but no biggie. I already have a way of using a number of if statements, but I thought this would be a fun way of doing things in a neater way and learn at the same time.

As always, thank all of you very much for your help!

Regards,
Christian

Here’s one way to implement magicFunction (not tested):

int numberBuffer = 0;
int foo = 0;
int bar = 0;

// return true if the variable name was found
bool magicFunction(const char *name, int value)
{

        struct {
                const char *name;
                int *ptr;
        } variables[] = {
                { "numberBuffer", &numberBuffer },
                { "foo",          &foo },
                { "bar",          &bar },
        };

        for (int i = 0; i < sizeof variables / sizeof variables[0]; ++i) {
                if (strcmp(name, variables[i].name) == 0) {
                        *variables[i].ptr = value;
                        return true;
                }
        }
        return false;
}

You just have to add a name/pointer pair to the variables array for each variable you want to set.

I find myself doing this sort of thing quite a lot where it would nice if C++ had the ability to use the text form of a variable name to use the variable to save typing :

// Preparing to send values from C++ variables to a browser client in JSON format:
root["cpa_custTzStdWeek"] = config.custTzStdWeek  ;
root["cpa_custTzStdDow"] = config.custTzStdDow  ;
root["cpa_custTzStdMonth"] = config.custTzStdMonth  ;
root["cpa_custTzStdHour"] = config.custTzStdHour  ;
root["cpa_custTzStdOffset"] = config.custTzStdOffset  ;

. . . 

// Retrieving the values (possibly updated) from the browser client:
config.custTzStdWeek =          server.arg("cpa_custTzStdWeek" ).toInt() ;
config.custTzStdDow =           server.arg("cpa_custTzStdDow" ).toInt() ;
config.custTzStdMonth =         server.arg("cpa_custTzStdMonth" ).toInt() ;
config.custTzStdHour =          server.arg("cpa_custTzStdHour" ).toInt() ;
config.custTzStdOffset =        server.arg("cpa_custTzStdOffset" ).toInt() ;

There could even be a better way of doing it.

RayLivingston:
That would be a lot more likely to work as:

Thank you for that. I did say that mine was pseudo code

...R

I was thinking of something like this:

String searchFor[] = {"myInt0", "myInt1", "myInt2"};
String inMessage;
char findSymbolTemp[16];

int myInt0;
int myInt1;
int myInt2;

int i;

void setup() {
}

void loop() {

  for (i = 1; i <= (sizeof(searchFor) / sizeof(searchFor[0])); i++); {
    if (inMessage.equals(searchFor[i])) {
      magicFunction(searchFor[i], 123);
    }
  }
}

The reason I want it like this is so that I can expand the number of variables to look for by just adding the names of them in searchFor and declare an int with the same name.

Right now I have something that looks like this:

String searchFor[] = {"myInt0", "myInt1", "myInt2"};
String inMessage;
char findSymbolTemp[16];

int myInt0;
int myInt1;
int myInt2;

int i;

void setup() {
}

void loop() {

  for (i = 1; i <= (sizeof(searchFor) / sizeof(searchFor[0])); i++); {
    if (inMessage.equals("myInt0")) {
      myInt0 = 123;
    }
    else if (inMessage.equals("myInt1")) {
      myInt1 = 123;
    }
    else if (inMessage.equals("myInt2")) {
      myInt2 = 123;
    }
  }
}

which requires a little bit more work, and like I said, I think that this would be a great opportunity to learn.

There is a lot in christops code that I don’t understand, and I don’t know what pointers are, but I guess it’s time to read about it.

chrstrvs:
Right now I have something that looks like this:

You could greatly simplify that by using an array to hold your integers and providing an index into the array. Then you would not even need an IF. You could do something like this (assuming the variable inMessage is a byte or int variable).

myArray[inMessage] = 123;

By the way it is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

...R

int myInt0;
int myInt1;
int myInt2;


struct NamedInt
{
  const char *name;
  int *pointer;
} NamedInts[] =
{
  {"myInt0", &myInt0},
  {"myInt1", &myInt1},
  {"myInt2", &myInt2}
};


const size_t NumberOfNamedInts = sizeof NamedInts / sizeof NamedInts[0];


void SetNamedInt(String name, const int value)
{
  for (size_t i = 0; i < NumberOfNamedInts; i++)
  {
    if (name.equals(NamedInts[i].name))
    {
      *(NamedInts[i].pointer) = value;
    }
  }
}


void setup()
{
  Serial.begin(115200);
  
  // Display initial values (0)
  Serial.println(myInt0);
  Serial.println(myInt1);
  Serial.println(myInt2);


  // Fill in random order
  SetNamedInt("myInt1", 456);
  SetNamedInt("myInt0", 123);
  SetNamedInt("myInt2", 789);


  // Display updated values
  for (size_t i = 0; i < NumberOfNamedInts; i++)
  {
    Serial.print(NamedInts[i].name);
    Serial.print(" = ");
    Serial.println(*(NamedInts[i].pointer));
  }
}


void loop() {}

Robin2:
You could greatly simplify that by using an array to hold your integers and providing an index into the array. Then you would not even need an IF. You could do something like this (assuming the variable inMessage is a byte or int variable).

myArray[inMessage] = 123;

By the way it is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with ‘\0’ (NULL).

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

…R

inMessage is a string (lower case), so that won’t work, but thanks for the tip. I’ll remember that for the future.

Yeah, I’ve read so many times that Strings isn’t the way to go. I’m working on replacing all Strings with char arrays.

Thanks for the tip about Serial input basics. I’ll have a look!

johnwasser:

int myInt0;

int myInt1;
int myInt2;

struct NamedInt
{
  const char *name;
  int *pointer;
} NamedInts =
{
  {“myInt0”, &myInt0},
  {“myInt1”, &myInt1},
  {“myInt2”, &myInt2}
};

const size_t NumberOfNamedInts = sizeof NamedInts / sizeof NamedInts[0];

void SetNamedInt(String name, const int value)
{
  for (size_t i = 0; i < NumberOfNamedInts; i++)
  {
    if (name.equals(NamedInts[i].name))
    {
      *(NamedInts[i].pointer) = value;
    }
  }
}

void setup()
{
  Serial.begin(115200);
 
  // Display initial values (0)
  Serial.println(myInt0);
  Serial.println(myInt1);
  Serial.println(myInt2);

// Fill in random order
  SetNamedInt(“myInt1”, 456);
  SetNamedInt(“myInt0”, 123);
  SetNamedInt(“myInt2”, 789);

// Display updated values
  for (size_t i = 0; i < NumberOfNamedInts; i++)
  {
    Serial.print(NamedInts[i].name);
    Serial.print(" = ");
    Serial.println(*(NamedInts[i].pointer));
  }
}

void loop() {}

It works! Cool!

The following are things I don’t understand and have to learn before I can use this:
struct
pointer
size_t

Now I have something to do for the rest of the night. It’s 9:27 pm here in Sweden =)

Thanks so much for the help!