Convert from string array to char* const - c++

I'm looking for a way to call execvp() in a C++ program that uses string arrays. So if, for example, I have an array of strings,
s[0] = "ls";
s[1] = "-l";
then, s[i].c_str() converts it to const char*. However, I need s[i] converted to a char* const to pass it to execvp(). Is there any way to do this in C++?

I was able to answer my own question. I had to convert the const char* to a char*.
However, since C++ doesn't allow conversion from const char* to char*, I had to create an extern C function. I converted the string s to a C-string (as a const char*), passed it to the extern C function. Within the C function I could then convert it from a const char* to a char* and subsequently pass it to execvp().

Related

conversion between char* and std::string and const char*

I am now using C++ to program a robot using PROS. Pros has a print function, which is taking in a const char*. Now, I'm using lvgl to create my own screen, and I want to replicate the print function. Like the printf() functions, I want it to include variadic params to do the %d effect (so it converts all the %? to the corresponding values). The problem now is about the conversions between functions. I wanted to make a convert function to convert a string and the variadic params into a complete string. I need to input is a string which is like "hey" and I'm unsure what the type name should be. I need to be able to get size, search in it for %ds but I need the function to return a const char* to pass onto the lvgl to pring on the screen. I am having a bad time trying to convert a string into an const char* for the out put of the convert function.
Also, I tried using the input type as a char*, and when I input a string like "hello" is says a error [ISO C++11 does not allow conversion from string literal to 'char ' [-Wwritable-strings]]. But instead, when is use a const char, the error disappears. Anyone knows why?
Thanks everyone for your kind help!
char* and const char* are two flavours of the same thing: C-style strings. These are a series of bytes with a NUL terminator (0-byte). To use these you need to use the C library functions like strdup, strlen and so on. These must be used very carefully as missing out on the terminator, which is all too easy to do by accident, can result in huge problems in the form of buffer-overflow bugs.
std::string is how strings are represented in C++. They're a lot more capable, they can support "wide" characters, or variable length character sets like UTF-8. As there's no NUL terminator in these, they can't be overflowed and are really quite safe to use. Memory allocation is handled by the Standard Library without you having to pay much attention to it.
You can convert back and forth as necessary, but it's usually best to stick to std::string inside of C++ as much as you can.
To convert from C++ to C:
std::string cppstring("test");
const char* c_string = cppstring.c_str();
To convert from C to C++:
const char* c_string = "test";
std::string cppstring(c_string);
Note you can convert from char* (mutable) to const char* (immutable) but not in reverse. Sometimes things are flagged const because you're not allowed to change them, or that changing them would cause huge problems.
You don't really have to "convert" though, you just use char* as you would const char*.
std::string A = "hello"; //< assignment from char* to string
const char* const B = A.c_str(); //< call c_str() method to access the C string
std::string C = B; //< assignment works just fine (with allocation though!)
printf("%s", C.c_str()); //< pass to printf via %s & c_str() method

invalid operands of types const char*

I am trying to make a new const char* b by adding a new string "hello" to original const char* a:
const char* a = some_code_here;
const char* b = (a + "_hello").c_str();
And the error I get is:
error: invalid operands of types const char* and const char [6] to binary operator+
Is there anything wrong I am doing?
Switch to strings, that is std::string.
Repeat after me, forget about using char or C-style strings.
As you have demonstrated, this is one of many issues.
Did I say switch to std::string?
Your char * is a pointer. Nothing more, nothing less, a pointer. A pointer to a single char; not a structure. The char data type doesn't have methods.
Switch to std::string.
You can add (concatenate) std::string.
Switch to std::string.
The std::string has the c_str() method. Don't use unless you understand the consequences; completely.
You can't arbitrarily add const char* in C++. These objects are just pointers to a contiguous section of memory, so adding them doesn't make sense. Instead, you should use the std::string class:
std::string a = "something";
std::string b = a + "_hello";

How to get a const char* function to work?

So I have this char const* blahblahblah(const char* s) function but when I try to use strcat(s, " ") or return s[k]in it it says
const char*s
Error: argument of type "const char*" is incompatible of parameter of type "char"
If I want the function to stay as is what should I change in my parameters in order for it to work?
If you declare const char* s, then you should not write strcat(s, " "), because strcat modifies s.
if you declare char const* reverseWordsOnly, then why do you return s[k]? s[k] is not a pointer.
EDIT:
This depends on what you want to do. I don't know what you want to do in this function.
If you don't modify s, then declaring const char* s is OK.
If you want to return char const *, then maybe you want to return &s[k] instead of s[k].
Maybe you want to return char *, then you can cast &s[k] using (char *)&s[k].
It's because the const on the left-hand-side of the * means that what's pointed to is immutable: strcat obviously needs to alter its parameter. And s[k] will refer to a char, not any sort of char *.

g++ strstr says invalid conversion from const char * to char *

I am converting a project written in C++ for windows. Everything is going fine (meaning I clearly see what needs to be changed to make things proper C++) until I hit this, which is my own little routine to find a keyword in along string of keyword=value pairs:
bool GetParameter(const char * haystack, const char *needle) {
char *search, *start;
int len;
len = strlen(needle) + 4; // make my own copy so I can upper case it...
search = (char *) calloc(1,len);
if (search == NULL) return false;
strcpy(search,needle);
strupr(search);
strcat(search,"="); // now it is 'KEYWORD='
start = strstr(haystack,search); <---- ERROR from compiler
g++ is telling me "Invalid conversion from const char * to char * "
(the precise location of the complaint is the argument variable 'search' )
But it would appear that g++ is dyslexic. Because I am actually going the other way. I am passing in a char * to a const char *
(so the conversion is "from char * to const char *" )
The strstr prototype is char * strstr(const char *, const char *)
There is no danger here. Nothing in any const char * is being modified.
Why is it telling me this?
What can I do to fix it?
Thanks for any help.
The background to the problem is that C defines the function strstr as:
char* strstr(const char*, const char*);
This is because C doesn't allow overloaded functions, so to allow you to use strstr with both const and non-const strings it accepts const strings and returns non-const. This introduces a weakness in C's already fragile type-system, because it removes const-ness from a string. It is the C programmer's job to not attempt to write via a pointer returned from strstr if you pased in non-modifiable strings.
In C++ the function is replaced by a pair of overloaded functions, the standard says:
7. The function signature strstr(const char*, const char*) shall be replaced by the two declarations:
const char* strstr(const char* s1, const char* s2);
char* strstr( char* s1, const char* s2);
both of which shall have the same behavior as the original declaration.
This is type-safe, if you pass in a const string you get back a const string. Your code passes in a const string, so G++ is following the standard by returning a const string. You get what you asked for.
Your code compiles on Windows because apparently the standard library you were using on Windows doesn't provide the overloads and only provides the C version. That allows you to pass in const strings and get back a non-const string. G++ provides the C++ versions, as required by the standard. The error is telling you that you're trying to convert the const return value to a non-const char*. The solution is the assign the return value to a const char* instead, which is portable and compiles everywhere.
Error is not regarding the arguments to stsrtr. Compiler is complaining about the conversion of the 'const char *' returned by strstr. You can't assign it to *start which is just char *
You can try one of these:
const char *start;
or
string start(strstr(haystack,search));
Although declaring start as const char* might suffice, what seems more appropriate to me is to use std::string objects instead:
#include <string>
#include <cctype>
#include <algorithm>
bool GetParameter(const char * haystack, const char *needle) {
std::string hstr(haystack), nstr(needle);
std::transform(nstr.begin(), nstr.end(),nstr.begin(), ::toupper);
nstr += "=";
std::size_t found = hstr.find(nstr);
if (found != std::string::npos) {
... // "NEEDLE=" found
}
else {
...
}
...
}
The conversion it is complaining about is from strstr(...) to start. Change the declaration of start to const char* start;
you can use such like:
start = const_cast<char *>(strstr( haystack, static_cast<const char *>(search) ));

char pointers, char arrays, and strings in the context of a function call

What is the difference between the line that does not compile and the line that does compile?
The line that does not compile gives this warning: deprecated conversion from string constant to 'char*'
Also, I'm aware casting (char *) on the string being passed in to the function would solve the problem, but I would like to understand why that's even necessary when the 2nd line compiles just fine.
class Student {
public:
Student( char name[] ) {
}
}
int main() {
Student stud( "Kacy" ); //does not compile
char name[20] = "Kacy"; //compiles just fine
}
The char[] signature in the parameter is exactly the same as char*. In C++, it is illegal to convert a string constant char const* (the string "Kacy") to a char* because strings are immutable.
Your second example compiles because the name is an actual array. There is no change to char*.
As a solution, change your parameter to take a const string array:
Student(char const name[]);
which again is the same as
String(char const *name);
though you're better off using std::string:
#include <string>
class String
{
public:
String(std::string name);
};
C++ string literals have type "array of n const char", which decays into const char * in your use case. The implicit conversion to char * (that is, discarding the const) you're trying is deprecated, so there's a warning. Change the type in the constructor's signature or make an explicit const-cast.
From the C++ standard:
An ordinary string literal has type "array of n const char" and static storage duration
The string
"Kacy"
is not an array of characters when the compiler produces the code. Instead, it will stash the string "Kacy" somewhere in memory, and produce a pointer to that place. So what you get is a const char * pointing at the string "Kacy\0".
If you change your constructor to:
Student(const char *nmae)
you can use it both as:
Student stud("Kacy");
and as this:
char name[20] = "Kacy";
Student stud2(name);
Note here that the compiler will generate code to FILL the array name with the characters in "Kacy", which is different from just usinv "Kacy" as an argument to the Student constructor.