0

I'm trying to instantiate and easily access an array of names in C++ using basic types in contiguous memory. I'm astounded that this is extremely difficult or complicated to do in C++ WITH ONLY basic types.

For some background, I am programming a microcontroller with limited memory, modest processing power, and it is handling serial communication over a network to 36 other microcontrollers sending continuous sensor data which is uploaded to a webserver. The shorter the refresh rate of the data, the better, so I prefer basic program features.

Not that I'm saying the more complicated stuff I've looked in other forums for, like an array of strings, has worked.

In my desperation, I was able to get this to work.

char names_array[] = "Bob\0\0Carl";
printf("%s",names_array); //outputs Bob
printf("%s",names_array + 5); //outputs Carl

This is a horrible solution though. My indexing is dependent on the longest name in the array, so if I added "Megan" to my list of names, I'd have to add a bunch of null characters throughout the entire array.

What I want to do is something like this:

char names_array[2] = {"Bob","Carl"}; //does not compile
printf("%s",names_array[0]);
printf("%s",names_array[1]);
//Error: A value of type "const char *" cannot be used to
//initialize an entity of type "char" in "main.cpp"

but that didn't work.

I want to loop through the names in my list and do something with each name, so at this point, this is my best solution.

char name0[] = "Bob";
loop_code(name0);
char name1[] = "Carl";
loop_code(name1);
.
.
.

I expect there's a reasonable way to make an array of pointers, each to an array of char terminated by null(s). I must be doing something wrong. I refuse to believe that a language like C++ is incapable of such a basic memory allocation.

15
  • 1
    Are you sure that char names_array[2] = {"Bob","Carl"}; ever compiled? Because it shouldn't. If it did, you should seriously consider switching to a more useful compiler… Commented Apr 30, 2019 at 1:22
  • 3
    char names_array[2] => const char* names_array[2] Commented Apr 30, 2019 at 1:24
  • It's complicated to do because you're not using features of the language to make it easier. But since that's your restriction, that isn't to say it's impossible, but that's just to explain why it might be harder. Commented Apr 30, 2019 at 1:25
  • but that didn't work -- I think this question may be closed, because of a typo. See here, Except for the C++ ISO warning, the text is not garbled. Commented Apr 30, 2019 at 1:26
  • It seems you want to use c++ as a glorified c. That is perfectly fine. You can use zero terminated strings and initialize an array of pointers. But beware that there is no guarantee that they will be contagious. Or you can have one large string with a separator embedded within. If all you want to do is just iterate over the list that might do. Commented Apr 30, 2019 at 1:35

2 Answers 2

1

You can, e.g., get an array of pointers to null-terminated strings:

const char* names_array[] = { "Bob", "Carl" };

and then

std::printf("%s", names_array[0]);
std::printf("%s", names_array[1]);

The problem with your attempt

char names_array[2] = {"Bob","Carl"};

is that you declare names_array to be an array of characters. This should never compile because what the = {"Bob","Carl"} essentially attempts to do is initialize each character in that array of characters with an entire array of characters of its own. A character is just a character, you cannot assign an entire array of characters to just an individual character. More precisely, initialization of a character array from a string literal is a special case of initialization [dcl.init.string] that allows a single string literal to be used to initialize an entire character array (because anything else doesn't make sense). What you actually want would be something more like an array of character arrays. However, the problem there is that you'd have to effectively pick a fixed maximum length for all strings in the array:

char names_array[][5] = { "Bob", "Carl" };  // each subarray is 5 characters in length

which would be potentially wasteful. You can flatten a series of multiple strings into one long array and then index into that, like you did with your first approach. The downside of that, as you've found out, is that you then need to know where each string starts in that array…

If you just want an array of string constants, a more modern C++ approach would be something like this:

#include <string_view>

using namespace std::literals;

constexpr std::string_view names[] = {
    "Bob"sv,
    "Carl"sv
};

The advantage of std::string_view is that it also has information about the length of the string. However, while std::string_view is compatible with most of the C++ standard library facilities that handle strings, it's not so simple to use it together with functions that expect C-style null-terminated strings. If you need null-terminated strings, I'd suggest to simply use an array of pointers to strings as shown at the very beginning of this answer…

Sign up to request clarification or add additional context in comments.

1 Comment

Nit const char* names_array[] better as const char *names_array[]. Not as likely to invoke confusion, e.g. char* a, b, c doesn't declare 3 pointers. char *a, b, c makes that clear.
0

char can has only one character.

If you want to use char, you can do it like

char name0[3] = "Bob";
char name1[4] = "Carl";
char *nameptr[2] = {&name0[0], &name1[0]};

Acutally, this pretty hard.

I suggest to you, use std::string.

std::string name[2] = {"Bob","Carl"};

this code is acceptable.

1 Comment

OP was very specific in saying they only wish to use basic types, so std::string is out.

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.