Ben Stott
Ben Stott

Reputation: 2218

Printing one variable based on the contents of another variable

I have a function similar to the following that takes an integer as a parameter, and using this integer I want to to access a specific variable. Of course, I can just casebash using the case/switch statement, or if/else, but this is far too dirty and I'm guessing there must be some form of elegant solution.

static unsigned char frame1[] = {...};
static unsigned char frame2[] = {...};
/*...*/
static unsigned char frame30[] = {...};

int select_frame(int frame_number){
  /* How can I use frame_number to select the correct frame variable without case/switch, if at all? */
}

I feel as though there could potentially be a stringstream method (or similar), though I'm not sure. Any suggestions? I'm happy to see solutions in either of C or C++.

EDIT: I feel I should note that most of these arrays will have over 500 individual elements in them, and thus it becomes a little impractical to combine them all into one giant array. If it's possible, I'm looking for a solution that avoids this method, though I'm currently seriously considering it.

Upvotes: 1

Views: 122

Answers (4)

Ise Wisteria
Ise Wisteria

Reputation: 11669

If your C compiler is C99 conforming, and the array is defined outside functions, compound literal like the following might meet the purpose.

static unsigned char *frames[] = {
  (unsigned char[]){ 1, 2, ... },
  (unsigned char[]){ 3, 4, ... },
  ...
};

int select_frame(int frame_number){
  ... frames[ frame_number ] ...
}

Upvotes: 0

Tony Delroy
Tony Delroy

Reputation: 106076

If you want to access one of the frames based on an integer, then simply put the frames into an array:

static unsigned char* frames[30];

frames[0] = (unsigned char*)strdup("first frame's char");
frames[1] = (unsigned char*)strdup("second frame's char");

Then you can directly and efficiently index to frames[i].

In C++, a more flexible approach is to use a std::vector<std::string> (as long as your numbers are contiguous) or even a std::map<int, std::string> (good if you have numbers with gaps, or want to insert/erase single elements often during runtime.

EDIT: helper function to create string literal source code from existing unsigned char arrays (off-the-top-of-my-head, tweaks may be needed):

void f(std::ostream& os, unsigned char* p)
{
    os << '"';
    for ( ; *p; ++p)
    {
        if (*p < ' ' || *p >= 127)
            os << '\\' << std::setw(3) << std::setfill('0') << std::oct << *p;
        else if (*p == '\\')
            os << "\\\\";
        else
            os << *p;
    }
    os << '"';
}

Then just call f(frame1); f(frame2); etc...

Upvotes: 4

iammilind
iammilind

Reputation: 69988

You can use 2D array and make it a single frames array variable. Or, if you are ok with using char array then you can use std::string.

static string frames[30] = { "frame1 string", "frame2 string", ..., "frame30 string" };
int select_frame (int frame_number)
{
  string &check = frames[frame_number];
}

Upvotes: 0

Delan Azabani
Delan Azabani

Reputation: 81384

I don't think that's possible in C or C++. If you can, why not have a

static unsigned char frame[30][]

Upvotes: 0

Related Questions