String Conversion error - c++

I made a struct of strings and every time I try and compare my strings, it says i am comparing ints and chars...but I am only comparing strings?
while(gap > 0){
passOk=true;
for(int i =0; i < *total-gap; i++)
if(strcmp(individualf->firstnames[i] , individualf->firstnames[i+gap])>0){
exchange(individualf[i], individualf[i+gap]);
passOk = false;
}
if(passOk)
gap /= 2;
}
}
MY complier error is: cannot convert ‘std::string {aka std::basic_string}’ to ‘const char*’ for argument ‘1’ to ‘int strcmp(const char*, const char*)’
if(strcmp(individualf->firstnames[i] , individualf->firstnames[i+gap])>0){

std::string has an operator>, use it:
if (individualf->firstnames[i] > individualf->firstnames[i + gap])
// stuff
If for some reason you must use strcmp, then just realize that std::string is not a const char*, and use std::string::c_str() to get a pointer to the string's memory:
if (strcmp(individualf->firstnames[i].c_str(), individualf->firstnames[i + gap].c_str()) > 0)
// stuff

You're treating C++ (STL) std::strings as old-school C strings. Forget all about C strings and just use the C++ ones.
If you need to compare them, they have a built-in compare method. If you need to play with case, etc, I highly recommend the Boost String Algorithms.

Related

C++ - using strcmp to compare which name comes first in alphabetical order

I'm new to C++ and trying to implement the lessThan() member function that compares the Person on the left-hand side (the this person) with the Person passed in as the parameter; a person is considered “less than” another if their name comes first in alphabetical order.
I made my function below but when I run it I get the error:
cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const char*’ for argument ‘1’ to ‘int strcmp(const char*, const char*)’
Aside from that, I was wondering if I'm using the this keyword and strcmp() function correctly? Should it be < 0?
bool Person::lessThan(Person* per){
if(strcmp(this->name, per->name) < 0){
return true;
}else{
return false;
}
}
All you need to do is return name < per->name; and be done with it since <std::string> allows for that comparison and it is the preferred method.
For completeness you could fix your code:
bool Person::lessThan(const Person* per) const {
return strcmp(this->name.c_str(), per->name.c_str()) < 0;
}
#Retired Ninja

Setting up an array of char using smart pointer and std::vector

I want to have an array of char[maxname]. My initial approach was the following
class char_list
{
char_list(int noc){names_.reserve(noc)}
std::vector<std::unique_ptr<char>> names_;
void setname( const char* name){ names_.push_back(name)};
}
When I try to invoke the routine by e.g.
char aux[100];
aux = 'asadsdsd'
const char* aux1 = aux;
setname(aux1);
I get the error
candidate function not viable: no known conversion from 'const char *' to
'const std::__1::__vector_base<std::__1::unique_ptr<char, std::__1::default_delete<char> >, std::__1::allocator<std::__1::unique_ptr<char, std::__1::default_delete<char> > > >::value_type' (aka
'const std::__1::unique_ptr<char, std::__1::default_delete<char> >') for 1st argument
_LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
I am using clang with C++17 standard.
In C++ you shall banish char[] and arrays in general. Normally you are expected to use std::vector and in the case of string, use std::string. Vector grows & shrink automatically and do memory management for you. std::string does the same but is specialized for string management.
So you code would look like:
std::vector<std::string> names;
Then you can do wonderful things like:
names.push_back("ABC");
And then you can easily retrieve your name:
std::string &name0 = names[0];
Or the char* equivalent(only for C interoperability):
const char *c_string = name0.c_str();
I want to have an array of char[maxname]
An array of arrays is called a 2-dimensional array.
constexpr unsigned N = 10; // 10 as an example.
char arr[N][maxname];

C++ error: cannot convert ‘std::basic_string<char>’ to ‘const char*’

I'm using a function to download a file.
void downloadFile(const char* url, const char* fname) {
//..
}
This is called like :
downloadFile("http://servera.com/file.txt", "/user/tmp/file.txt");
This working fine.
But I want to change the URL to be a value from an array. The array stores encrypted values which when decrypted are strings, so I get the issue error: cannot convert ‘std::basic_string<char>’ to ‘const char*’
I've tried:
string test = decode(foo[5]);
const char* t1= test.c_str();
downloadFile(t1 "filename.txt", "/user/tmp/file.txt");
downloadFile(t1 + "filename.txt", "/user/tmp/file.txt");
and
downloadFile((decode(foo[5]).c_str()) + "filename.txt", "/user/tmp/file.txt");
which gives:
error: invalid operands of types ‘const char*’ and ‘const char [17]’ to binary ‘operator+’
What am I doing wrong ?
Thanks
C-strings can't be concatenated with +.
Use std::string::+ instead:
downloadFile((test + "filename.txt").c_str(), "/user/tmp/file.txt");
Note that c_str only returns a pointer to the std::string's internal character array, so it's valid only during the execution of the downloadFile function.
Try this:
downloadFile((decode(foo[5]) + "filename.txt").c_str(), "/user/tmp/file.txt");
The operator+ is not defined for char arrays.
The main problem in your code is that you are trying to use operator+ to concatenate raw C strings (i.e. raw const char* pointers, or raw char [] arrays), which doesn't work.
In C, you should use proper library functions (like strncat or safer variants) to do that; but since you are using C++, you can do better, and write easier code: just use a C++ string class, like std::string.
In fact, the C++ standard library offers convenient overloads for operator+ that work with std::string, so you can concatenate C++ strings in an easy, intuitive and safe way; for example:
// Build your URL string
std::string test = decode(foo[5]);
std::string url = test + "filename.txt";
// Use std::string::c_str() to convert from C++ string
// to C raw string pointer const char*
downloadFile(url.c_str(), "/user/tmp/file.txt");

C++ invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]

WARNING: Extremely limited knowledge of C++ and coding in general. Please refrain from advanced terminology.
for ( i = 0; i < answer.size(); ++i) {
if (guess == answer.at(i)) { //to display correct letters in answerDisplay
answerDisplay.replace( (2 * i), 1, answer.at(i) );
correctGuesses += 1;
}
Given: answerDisplay and answer are strings.
When I run my program there is a compile-time error at the third line of what I've posted saying:
invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
What's the problem? How can I fix it? All other posts with this error talked about pointer characters but I don't know what those are.
Pointer characters are they way plain strings are implemented in C and C++. In C++ you have the nice class std::string, but string literals are still array of characters. And arrays in C and C++ can be seen as pointers.
For example, "hello" is of type const char[6] (5 characters plus the ending NUL), but it can be trivially converted to const char *, and that in turn can be converted to std::string.
In line 3, the only relevant code is a call to the member function std::string::replace(). There are a lot of overrides of this function (different sets of parameters to be used), but the one the compiler is trying to use is this one:
string& replace (size_t pos, size_t len, const char* s);
As you can see, it takes two numbers and a const char * (an old-string/char-array). But you are passing as third parameter answer.at(i) that is of type char. Hence the error:
invalid conversion from ‘char’ to ‘const char*’
Solution? You can build a string from that char:
answerDisplay.replace( (2 * i), 1, std::string(1, answer.at(i))
Or you can get a substring of the original string instead of a plain character.
answerDisplay.replace( (2 * i), 1, answer.substr(i, 1))

atoi and string array

I have a string array and an integer array. I want to convert the elements of string array to integer and then store them in the integer array. I wrote this code :
string yuzy[360];
int yuza[360];
for(int x = 0;x<360;x++)
{
if(yuzy[x].empty() == false)
{
yuza[x]=atoi(yuzy[x]);
cout<<yuza[x]<<endl;
}
else
continue;
}
this piece of code gives this error:
error: cannot convert 'std::string {aka std::basic_string}' to 'const char*' for argument '1' to 'int atoi(const char*)'
When I write the content of the string (-75dbm) in atoi function it works fine. But when I write (yuzy[x]), I get the error. How can I make atoi works well with string array?
Thanks.
atoi() takes C strings (char pointers) and not C++ string objects. Use
atoi(yuzy[x].c_str());
instead.
As an alternative to atoi, you could use std::stoi and related functions, if you have C++11 support.
yuza[x] = std::stoi(yuzy[x]);
atoi accept a c-style string as parametter, so, you could use atoi(yuzy[x].c_str());