How to get a const char* function to work? - c++

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 *.

Related

Convert from string array to char* const

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().

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";

Converting string to const* char

I have two string declarations:
killerName
victimName
I need to convert these two string values to const* char.
Example of how I use my method:
if (killer.IsRealPlayer) {
killerName = killer.GetName(); -- need to convert to const* char
victimName = victim.GetName(); -- need to convert to const* char
Notice(killerName + "has slain:" + victimName, killer.GetMapIndex(), false);
}
Some error I receive:
Error 111 error C2664: 'Notice' : cannot convert parameter 1 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'const char */
It seems that function Notice have the first parameter of type const char * However the expression passed to it as the first argument
killerName + "has slain:" + victimName
has type std::string
Simply call the function the following way
Notice( ( killerName + "has slain:" + victimName ).c_str(), killer.GetMapIndex(), false);
Notice(string(killerName + "has slain:" + victimName).c_str(), killer.GetMapIndex(), false);
std::string::c_str() gives the const char* to the buffer. I think that's what you want.
See: http://www.cplusplus.com/reference/string/string/c_str/
As others already wrote, the result of killerName + "has slain:" + victimName is of type std::string. So, if your Notice() function expects a const char* as first parameter, you must convert from std::string to const char*, and since there is no implicit conversion defined for std::string, you must call the std::string::c_str() method:
Notice((killerName + "has slain:" + victimName).c_str(), killer.GetMapIndex(), false);
However, I'd like to ask: why do you have Notice() expecting a const char* as first parameter?
Would it be better to just use const std::string&? In general, in modern C++ code, you may want to use string classes like std::string instead of raw char* pointers.
(Another option would be to have two overloads of Notice(): one expecting a const std::string& as first parameter, and the other one expecting a const char*, if for some reason the const char* version does make sense in your particular context; this double overload pattern is used e.g. in the std::fstream constructor.)

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) ));

Convert const std::vector<std::string> to const char **

I have a function with signature like this:
void foo(const std::vector<std::string>& args)
{
...
}
I want convert vector args to const char ** (just like argv in main). How this can be done? We can't actually make a char ** array because then it (obviously) fails to convert args[i].c_str() that is of type const char * to char *.
The only (ugly) way I can think of is to use const_cast to cast from const char * to char *.
Would anyone suggest more elegant way of doing this? I should note I can use only c++03 features.
Thanks in advance.
It can't be done without an extra array. A const char** means "a pointer to a pointer to const char" - so you need a place where there are actual pointers to char to point to.
So you need to create that array.
struct c_str { const char* operator ()(const std::string& s) { return s.c_str(); } };
std::vector<const char*> pointers(args.size());
std::transform(args.begin(), args.end(), pointers.begin(), c_str());
// If you really want to be compatible with argv:
pointers.push_back(0);
// &pointers[0] is what you want now