Const char fake array issue

Hello people of the Internet!

I have a coding problem, let’s see if there’s a solution.

We have a line of code that looks like this.

const char * Test = “Apple\n” “Banana\n” “Orange\n”;

It’s not an array but let’s call it a “fake array”. If this would have been a real array then the problem wouldn’t exist. Unfortunately I cannot change it in this case as it’s a part of a visual roller that needs it to be like this.

Here comes the problem. I want to be able to have a function that gives me a value seen in Test based on position. For example if I want to get Orange returned from Test, I would give the function position 1 (as the first position is 0). A function call like that could look like this.

// Test is our fake array above. 1 is the position we want the value of.
Serial.print(returnValueFromPos(Test, 1));
// Serial print should return the word Orange.

I appreciate your help. Thanks!

Is it compiled?
it should be defined as

1 Like

Thanks for your reply.

It’s compiled, but adding [] should work as well. So let’s say I add [] then how can I get the value at a position?

This is a variable from LVGL (Little VGL). They define a roller “array” like I wrote in my first post. Why they do this I don’t know.

const char * const Test[] = {“Apple\n”, “Banana\n”, “Orange\n”};

Test[0]
Test[1]
Test[2]
1 Like

Unfortunately I don’t think I can do it this way. Here’s a print screen from LVGL examples, they use these “fake arrays” for some reason.

This is exactly the way to do it:

const char * const Test[] = {"Apple\n", "Bannan\n", "Orange\n"};

void setup() {
  Serial.begin(115200);
  Serial.println(Test[0]);
  Serial.println(Test[1]);
  Serial.println(Test[2]);
}

void loop() {
}
1 Like

Yes I agree. But that will not work with the LVGL roller function as they do not use a real array. Take a look at this link. Search for “Styling the roller” then expand that code example and look for “const char * opts”.

Post the code you're talking about. BTW, there is no such thing as a "fake array".

1 Like

I know there is no such thing as a fake array. I’m simply trying my best to explain.

In a nutshell this is an array, aka a fake array.

“One” “two” “three”

LVGL is a big and respected library for graphics. They have a widget called a Roller. To feed this roller with values you give it the Test variable I posted in my first post.

I agree that using an array would be the proper way of doing it. But they didn’t do that. Hence why I have the coding problem I have.

My question was not how to make an array, it was on how to extract the value from the positions in variable Test. And if it’s even possible.

But, I can't see it. Post a GitHub link.

1 Like

Unfortunately this code example is not on git. But I copied the full example from LVGL’s documentation.

static void event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj = lv_event_get_target(e);
    if(code == LV_EVENT_VALUE_CHANGED) {
        char buf[32];
        lv_roller_get_selected_str(obj, buf, sizeof(buf));
        LV_LOG_USER("Selected value: %s", buf);
    }
}

/**
 * Roller with various alignments and larger text in the selected area
 */
void lv_example_roller_2(void)
{
    /*A style to make the selected option larger*/
    static lv_style_t style_sel;
    lv_style_init(&style_sel);
    lv_style_set_text_font(&style_sel, &lv_font_montserrat_22);

    const char * opts = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10";
    lv_obj_t * roller;

    /*A roller on the left with left aligned text, and custom width*/
    roller = lv_roller_create(lv_scr_act());
    lv_roller_set_options(roller, opts, LV_ROLLER_MODE_NORMAL);
    lv_roller_set_visible_row_count(roller, 2);
    lv_obj_set_width(roller, 100);
    lv_obj_add_style(roller, &style_sel, LV_PART_SELECTED);
    lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_LEFT, 0);
    lv_obj_align(roller, LV_ALIGN_LEFT_MID, 10, 0);
    lv_obj_add_event_cb(roller, event_handler, LV_EVENT_ALL, NULL);
    lv_roller_set_selected(roller, 2, LV_ANIM_OFF);

    /*A roller on the middle with center aligned text, and auto (default) width*/
    roller = lv_roller_create(lv_scr_act());
    lv_roller_set_options(roller, opts, LV_ROLLER_MODE_NORMAL);
    lv_roller_set_visible_row_count(roller, 3);
    lv_obj_add_style(roller, &style_sel, LV_PART_SELECTED);
    lv_obj_align(roller, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(roller, event_handler, LV_EVENT_ALL, NULL);
    lv_roller_set_selected(roller, 5, LV_ANIM_OFF);

    /*A roller on the right with right aligned text, and custom width*/
    roller = lv_roller_create(lv_scr_act());
    lv_roller_set_options(roller, opts, LV_ROLLER_MODE_NORMAL);
    lv_roller_set_visible_row_count(roller, 4);
    lv_obj_set_width(roller, 80);
    lv_obj_add_style(roller, &style_sel, LV_PART_SELECTED);
    lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_RIGHT, 0);
    lv_obj_align(roller, LV_ALIGN_RIGHT_MID, -10, 0);
    lv_obj_add_event_cb(roller, event_handler, LV_EVENT_ALL, NULL);
    lv_roller_set_selected(roller, 8, LV_ANIM_OFF);
}

Why are you confusing others and yourself?
This variable is an ordinary string, there is no fake array here. Regular values with separator \n

Right. And you can use the regular cstring search functions to step through it and locate the positions of the "\n" characters. From those you can determine the indices for where the elements start.

It’s not a string, it’s a char. And I wrote it as such above. I clearly called it a “fake array” to try to explain as best as I could in words.

I asked how to get a value from a specific location in that string, “fake array”, char, or whatever you want to call it.

I also asked very nicely. If you don’t know how to solve this coding problem then please don’t reply to the thread.

Ps, sorry I’m not an expert like you guys. Hence me asking for help here.

Thanks.

NO!
"ops" is a pointer to a null-terminated, consecutive group of ASCII characters in memory. That makes it a cstring (aka string). It's also equivalent to an array for most purposes.

Well, I clearly hurt your feelings by asking for help.

Thanks anyway. I’ll seek help elsewhere.

Not at all. My Post #13 and #15 answer your question.

That might be the case but they don’t answer them in a way that make me understand. As I’m not at the same level of expertise as you.

consider

Output

  0  Apple
  1  Banana
  2  Orange

Code:

#include <stdio.h>
#include <string.h>


// -----------------------------------------------------------------------------
char  fakeBuf [80];

int
fake (
    const char *s,
    const char *sep,
    char   *fakePtrs [])
{
    strcpy (fakeBuf, s);

    int n = 0;
    fakePtrs [n++] = strtok (fakeBuf, sep);

    while ( (fakePtrs [n++] = strtok (NULL, sep)))
        ;
    return n-1;
}

// -----------------------------------------------------------------------------
char *fakePtrs [10];
int
main ()
{
    int N = fake ("Apple\nBanana\nOrange", "\n", fakePtrs);

    for (int n = 0; n < N; n++)
        printf ("  %d  %s\n", n, fakePtrs [n]);
    
    return 0;
}
1 Like

Thank you for such a complete example. It’s greatly appreciated!

Will test it tomorrow when I’m at the computer.