C++ - Error Conversion from const char* to char* - c++

I am having an issue receiving this error when compiling code similar to the below.
I am getting this error: invalid conversion from 'const char*' to 'char*' [-fpermissive].
I am unsure why as the strchr function accepts const char* ? maybe I am confused here. I have looked at other people having this same error on this site but I still don't see the solution clearly.
People had mentioned UNION? I have no clue how to use this keyword and was wondering if I could get clarification.
Could someone explain why this is happening or how is the safest/best method to resolving this error? I have other errors just like this in other spots in my code in the same situation.
#include <strings.h>
#include <cstring>
#include <string>
#include <stdio.h>
int main()
{
validURL ('www.why_CPP_hates_me.com');
return 0;
}
bool validURL (const char *url)
{
char *q = strchr (url, '?');
...
return true;
}

The right way to this is:
#include <cstring>
#include <string>
#include <stdio.h>
bool validURL(const char *url); // Must forward declare or prototype the
// function before calling
int main()
{
validURL("www.why_CPP_hates_me.com"); // Single quotes are for single chars
// Double quotes are for string
// literals, which create a const char*
return 0;
}
bool validURL(const char *url)
{
const char *q = strchr(url, '?'); // You have to assign to a const char*
// to maintain const correctness.
// strchr() has const char* and char*
// overloads. But you have to assign to
// the correct type.
return true;
}
Or if you wanted to you could do this:
bool validURL(const char *url)
{
char *q = strchr(const_cast<char*>(url), '?');
// Casting away const is not recommended generally. Should be careful.
return true;
}

Related

Assigning const std::string to std::string in c++

I am trying to assign a const std::string variable to std::string variable.But getting some memory related error. code is like below:
#include <iostream>
#include <string>
using namespace std;
std::string sender1;
std::string fun()
{
const std::string sender = "hi";
sender1.assign(sender);
}
int main()
{
fun();
cout<<sender1<<endl;
return 0;
}
You've forgotten a return in fun. If you change that function like this:
std::string fun()
{
const std::string sender = "hi";
sender1.assign(sender);
return sender;
}
then the code will compile and run fine.
I got the answer finally.
We need to declare a char * globally. Then using const_cast <char *> we can convert the constant string to char and assign it.
Example: in .h file:
char * abc;
in .cc file:
func()
{
const std::string cde = "Hello";
//now to use this constant string in another function,we use const cast and
//assign it to abc like below
abc = const_cast <char *>(cde.c_str());
}

Why I am fail my convert string to a C-string trying this way?

My code in VS2019 is not working.
In the last line of code compiler throws an error.
#include <iostream>
#include <string>
using namespace std;
struct struct1
{
string name;
};
void main()
{
struct1* obj1 = new struct1();
obj1->name = "Hello";
// compiler says 'initializing': cannot convert from 'const _Elem *' to 'char [25]'
char str[25] = (obj1->name).c_str();
}
c_str() returns a pointer to the start of the string's character data. You'll need to copy the characters into your array using something like strncpy().
there is a lot of ways to do this
but first you should change the manner of char array initialization because you made it wrongly.
this is the same program but working
#include <iostream>
using namespace std;
struct struct1
{
string name;
};
int main()
{
struct1* obj1 = new struct1();
obj1->name = "Hello";
char str[25] = "";
memcpy(&str,obj1->name.c_str(),obj1->name.size());
cout << str << endl;
}

Cannot Convert 'char (*)[200]' to 'char**'

#include <iostream>
#include <string.h>
using namespace std;
void ArrayTimesThree(char*, const char*);
int main()
{
char s1[200], s2[200], circleword[200];
cin.getline(s1, 200);
cin.getline(s2, 200);
ArrayTimesThree(circleword, s1);
cout<<circleword[1];
}
void ArrayTimesThree(char *dest[], char *source[])
{
*dest[0] = NULL;
strcat(*dest, *source);
strcat(*dest, *source);
strcat(*dest, *source);
}
main.cpp|21|error: cannot convert 'char (*)[200]' to 'char**' for argument '1' to 'void ArrayTimesThree(char**, char**)'
You're passing ArrayTimesThree a char*, however, in the method signature you're telling it to expect a char**. Don't forget that that using the [] operator counts as a dereference. Try this:
#include <iostream>
#include <string.h>
using namespace std;
void ArrayTimesThree(char*, char*);
int main()
{
char s1[200], s2[200], circleword[200];
cin.getline(s1, 200);
cin.getline(s2, 200);
ArrayTimesThree(circleword, s1);
cout<<circleword[1];
return 0;
}
void ArrayTimesThree(char *dest, char source[])
{
dest[0] = '\0';
strcat(dest, source);
strcat(dest, source);
strcat(dest, source);
}
Disclaimer: I'm not sure what exactly you're expecting out of this code, so I cannot guarantee the logic is correct; however, this will take care of your compiler errors and seems to function correctly for how the code is written.
The problem is really just because your initial declaration of ArrayTimesThree (which is the 'correct' one) doesn't match the definition you later give (which is wrong, in fact). Change your definition as below and it works:
void ArrayTimesThree(char* dest, const char* source) // Needs to be the same as in the previous declaration!
{
dest[0] = '\0'; // Don't assign a string pointer to NULL! Instead, set its first character to the nul character
// strcpy(dest, ""); // ALternatively, use strcpy with an empty string to clear "dest"
strcat(dest, source); // strcat takes char* and const char* arguments ...
strcat(dest, source); // ... so there is no need to 'deference the values ...
strcat(dest, source); // ... now that the argument types have been 'corrected'
}
Incidentally, I notice that the input value for s2 in your main function is never actually used … is this what you intend, for now?

string to char* conversion

I am in a code base where there are lots of function calls to functions that take a pointer as an argument. However, the function call passes a "string" object as if it's pointer. The following code is shown to give you an idea.
#include <vector>
#include <unordered_map>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
using namespace std;
void dum(char *s) {
printf("%s\n", s);
}
operator char* (string s) {
return s.c_str();
}
int main(int argc,char *argv[]) {
string st("Hello world");
dum(st);
return 0;
}
I am not allowed to change the syntax for all these functions or function calls. One possible solution I came up is to add a operator overload, but unfortunately it doesn't work, here is the error from g++ (ver 4.7.3), command line: g++ -std=c++11 te2.cc
error: ‘operator char*(std::string)’ must be a nonstatic member function
Any ideas? Thanks.
UPDATE1
#ferruccio's answer reminded me to mention that there are function calls like
dum(dum2());
where dum2() is a function is like:
string dum2() {
string s;
//.....
return s;
}
So the wrapper like the following doesn't work (), compiler gives error no matching function for call to ‘dum(std::string)’
void dum(string &s) {
dum(s.c_str());
}
operator char* (string s) {
return s.c_str();
}
This is broken (if it was allowed). When this function returns, s no longer exists. So a pointer to its contents is of no use.
You could add a simple function overload for each function that takes a char*. e.g.
void dum(const string& s) {
dum(s.c_str());
}

How to use qsort for string in C++

I want to use qsort function to sort the characters in the strings using C++.
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int compare_str(void const *a,void const *b){
char const *aa=(char const *)a;
char const *bb=(char const *)b;
if(*aa==*bb) return 0;
else if(*aa>*bb) return 1;
else return -1;
}
int main(){
string str="cake";
int len=str.length();
qsort(str,len,sizeof(str[0]),compare_str);
cout<<str;
return 0;
}
But it throws :
20 42 [Error] cannot convert 'std::string {aka std::basic_string<char>}' to 'void*' for argument '1' to 'void qsort(void*, size_t, size_t, int (*)(const void*, const void*))'
It would be great if anyone could provide an efficient way to do this.
I strongly recommend the modern method of
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string s("cake");
std::sort(s.begin(), s.end());
std::cout << s << std::endl; // Prints "acek".
return 0;
}
Plus, using std::sort over qsort allows the compiler to optimize better, so it's a win-win...
Your comparator for qsort expects C strings, not C++ std::strings. You should either declare str to be char str[]
char str[] = "cake";
qsort(str, strlen(cake), sizeof(char), compare_str); // Consider renaming to compare_char
or (better) use std::sort:
string str = "cake";
sort(str.begin(), str.end());
If you really want to do this, just pass a pointer to the string's contents:
qsort(str.c_str(),len,sizeof(str[0]),compare_str);
That said, you really should consider using the functions provided in the STL rather than those from the old C library...
You should use the function sort() under the header <algorithm>. This function is very flexible and you can use it in different manner. For sorting as you wish in question you can just write:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s="cake";
sort(s.begin(), s.end());
cout << s << endl;
return 0;
}
//output: acek
again by using sort() we can implement it in a range. If you want to sort first two element , the code will be
sort(s.begin(), s.begin()+2);
for above code the output will be
//output: acke
so if we want to sort first n element then we can write
sort(s.begin,s.begin()+n);
we can also modify the sort function. In that case we have to pass three parameter instead of two. The third parameter will be a functions which returns a bool value.For example , if we want to sort in descending order then our code will be like this
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
bool desc(char i, char j)
{
return i>j;
}
int main()
{
string s="cake";
sort(s.begin(), s.end(),desc);
cout << s << endl;
return 0;
}
//output: keca
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int compare_str(void const *a,void const *b){
char const *aa=(char const *)a;
char const *bb=(char const *)b;
if(*aa==*bb) return 0;
else if(*aa>*bb) return 1;
else return -1;
}
int main(){
string str="cake";
int len=str.length();
qsort(const_cast<char*>(str.c_str()),len,sizeof(str[0]),compare_str);
cout<<str<<endl;
return 0;
}