How to handle C-style Strings

Hi all, I seem to run across this a lot where old C code uses this shorthand style to create an array of pointers to C-strings:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

void existing_function(char* t){
        while(*t){
                printf("%c", *t++);
        }
}

int main(){
        int size = 2;
        char* things[] =
        {
            "Thing One",
            "Thing Two"
        };
        existing_function(things[0]);
        return 0;
}


The problem is g++ will flag a warning:

 
warning: ISO C++ forbids converting a string constant to ‘char*’


Is there an elegant way to initialize the C strings as C++ objects (string, vector, etc), then convert it back to C-String char* for the function? Note it needs to resolve back to a string pointer for the original function, which assume it cannot be modified. I created a fictitious existing_function() to indicate that the original C coded function needs a char* as an argument.

thank you,
Scott
Last edited on
You are not supposed to modify the data of a string literal so C++ wants you to use const char*. If you use some legacy library that takes a non-const char* you will have to cast it, assuming you know that th funcon does not modify the string.

1
2
3
4
5
6
const char* things[] =
{
	"Thing One",
	"Thing Two"
};
existing_function(const_cast<char*>(things[0]));


If you are not sure the function doesn't modify the string you might want to copy the string and pass the copy to the function instead, just to be safe.

1
2
std::string copy = things[0];
existing_function(copy.data());
Last edited on
Oh, that makes sense. And thanks for the data() function suggestion. Thanks for your response!
Last edited on
I think this is more thematic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdio>

void existing_function(const char** arr, int arr_size)
{
    for (int i=0; i<arr_size; ++i, ++arr)
    {
        printf("%s\n", *arr);
    }
}

int main()
{
    int size = 2;
    const char* things[] =
    {
        "Thing One",
        "Thing Two",            
    };
    existing_function(things, size);
    return 0;
}


Or if you don't know the array size, have some final string in there, like a blank one, "", and it could look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <cstdio>
#include <cstring>

void existing_function(const char** arr)
{
    while (strcmp(*arr,"") != 0)
    {
        printf("%s\n", *arr);
        arr++;
    }
}

int main()
{
    const char* things[] =
    {
        "Thing One",
        "Thing Two",
        ""
    };
    existing_function(things);
    return 0;
}
Yes, this does look more thematic. I've never used char**, so now I know how it's used!

For now, I'm trying not to modify the functions. The function prototype in my case is: existing_function(char*), so I cannot modify it by adding char** or an int. Although I think it's a more elegant solution (and I think it may have been the original intent of the programmer, but I don't know). I may modify the function at some point but I'm reluctant to do that because I don't know how it will impact other calls to it. If I can get away with modifying the calling routine I'll leave it at that.

thanks again,
Scott
Topic archived. No new replies allowed.