1

I have the following code:

char switch_list[] = {
    "PINB >> 7", 
    "PIND >> 1", 
    "PINB >> 1", 
    "PIND >> 0}"
};

void values(void){
    uint8_t switch_value = 0;
        if (i == 0){
            switch_value = (PINB >> 7) & 1; 
        }
        if (i == 1){
            switch_value = (PIND >> 1) & 1;
        }
        if (i == 2){
            switch_value = (PINB >> 1) & 1;
        }
        if (i == 3){
            switch_value = (PIND >> 0) & 1;
        }
        SOME OTHER OPERATIONS GO HERE
}

I need to interpret the switch_list values as unsigned integers somehow, but I am not able to make any changes to the array (it needs to remain a char array). PINB and the others have defined 8 bit value in the libraries. I would like to create a for loop that looks something like this:

uint8_t switch_value = 0;
    for (int i = 0, i < sizeof(switch_list)/sizeof(switch_list[0]); i++){
            switch_value = **********[i] & 1; 
         SOME OTHER OPERATIONS GO HERE
        }
}

Where ********* is the same as switch_list but instead of being of char type, it is uint8_t. Can anyone provide any tips?

10
  • you want to read the char array, extract the specific variable name (PINB or PIND) and then perform a shift on it and return as a uint8? Commented May 23, 2018 at 7:08
  • Extract the value, return it as a uint_8 then perform as shift on it. Or just literally insert the text of the array index into that for loop Commented May 23, 2018 at 7:10
  • Maybe I'm misunderstanding your question but it seems to me you are trying to get a text string executed as code (!?). That's not possible. Commented May 23, 2018 at 7:14
  • How are those PINx defined? Commented May 23, 2018 at 7:19
  • You could make an array of function pointers, e.g. uint8_t f0() {return PINB >> 7;} or just make a support function if you don't like all the if statements inside the loop. Commented May 23, 2018 at 7:19

2 Answers 2

1

You can use your knowledge about the array and create a function to convert your values from "PINB >> 7" to PINB >> 7. The assumptions I made are:

  1. The string always starts with "PIN" and then has a "B" or a "D" (can be easily modified )
  2. The string will then do an operation (currently I only support ">>" but this can too be easily modified)
  3. Last char in the string is a 1-char number (again, can be modified according to your knowledge about the string)

Using that, I can create a convert function

unsigned int convert(char * p);

/* PINB and the others have defined 8 bit value in the libraries
   so I'm making up their values here for convenience */
unsigned int PINB = 1024;
unsigned int PIND = 2048;

int main(){
    // deleted your ending }
    // and changed the type of the array
    char* switch_list[] = {
        "PINB >> 7", 
        "PIND >> 1", 
        "PINB >> 1", 
        "PIND >> 0"
    };

    unsigned int switch_value;
    // , should be ;
    // don't compare signed with unsigned
    for (unsigned int i = 0; i < sizeof(switch_list)/sizeof(switch_list[0]); i++){
        switch_value = convert(switch_list[i]); 
        printf("%u\n", switch_value);
    }

    return 0;
}

// assuming string must be exactly long as "PINB >> 7"
unsigned int convert(char * p){
    if(!p || strlen(p) != strlen("PINB >> 7")){
        printf("error\n");
        return (unsigned)-1;
    }

    unsigned int n;
    // use a string compare or, in your case, since only the 4th char is different:
    if(p[3] == 'B')
        n = PINB;
    if(p[3] == 'D')
        n = PIND;
    // note I'm not handling a case where the 4th letter isn't {'B', 'D'}, according to my assumption (the 1st).

    // use your knowledge about the string inside switch_list
    return n >> (p[strlen(p) - 1] - '0');
}
Sign up to request clarification or add additional context in comments.

Comments

1

Assuming the PINx thingies would evaluate to a type PIN_T you can do:

#include <stdlib.h> /* for size_t */
#include <inttypes.h> /* for uint8_t */

/* other include here */


struct switch_s
{
  PIN_T * ppin;
  uint8_t offset;
};

struct switch_s switches[] =
{
  {&PINB, 7},
  {&PIND, 1},
  {&PINB, 1},
  {&PIND, 0},
  /* more here */
};

int main(void)
{ 
  for (size_t i; i < sizeof switches / sizeof *switches; ++i)
  {
    uint8_t switch_value = (*switches[i].ppin >> switches[i].offset) & 1;

    /* Work with switch_value here ... */
  }
}

1 Comment

IMO, this is by far the best approach. I'm not sure that &PINx is correct but that's not important. The principle is what's important.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.