no matching function for call basic_string::copy - c++

I'm very new to C++ and have been fidgeting around with it for awhile. If any insight is available with these errors I would be in great gratitude. The following program should produce the following result:
#include <iostream>
#include <string>
using namespace std;
string Cut(string &strString, int nStart, int nLength)
{
string strCopy;
strString.copy(strCopy, nLength, nStart);
strString.erase(nStart, nLength);
return strCopy;
}
int main()
{
string strHate = "I hate tuna.";
cout << strHate << endl;
string strTuna;
strTuna = Cut(strHate, 8, 4);
cout << strHate << endl;
cout << strTuna << endl;
}
should produce
I hate tuna.
I hate .
tuna
however, instead I get this error message:
9|error: no matching function for call to 'std::basic_string<char>::copy(std::string&, int&, int&)'
Much appreciated,
KleptoKat

As referenced here, the function std::string.copy takes a parameter of type char *, you you've given it a parameter of type string
This is a better solution:
string Cut(string &strString, int nStart, int nLength){
string strCopy (strString, nStart, nLength);
strString.erase(nStart, nLength);
return strCopy;
}
This creates the new string from the old string directly from the constructor, so it's a little more elegant.
Just so you know why the error occurred, the data types of your variables (int, char, string, etc) have to match the data types that the function expects to receive. If you don't know what data types a function expects to receive, you can always look it up on Google.
Also, you need to use:
strTuna = Cut(strHate, 7, 4)
Instead of:
strTuna = Cut(strHate, 8, 4)
This is because the first character of the string has a position of 0 instead of 1.

Using string::substr in your case is probably more appropriate:
string Cut(string &str, int nStart, int nLength)
{
string strCopy = str.substr(nStart, nLength);
str.erase(nStart, nLength);
return strCopy;
}

Related

How to use pointer to string in cpp?

I am studying pointers in C++. I have studied call by value and call by reference concept. I am trying to create a function to reverse a string which accepts a pointer to string and the size of string. The code is as follow
void reverse(string* str, int size)
{
int start = 0;
int end = size - 1;
while(start < end)
{
swap(*str[start++], *str[end--]);
}
}
int main()
{
string str = "Something";
reverse(&str, str.length());
cout << "Reversed string: " << str << endl;
return 0;
}
I am getting this error:
error: no match for ‘operator*’ (operand type is ‘std::string’ {aka
‘std::__cxx11::basic_string’})
12 | swap(*str[start++], *str[end--]);
I don't want to use the character array, is there way to do it?
Someone please explain, what's wrong in my code. Thank you.
Here is the simple fix. You don't need to change anything except a few lines.
#include <iostream>
#include <algorithm>
#include <cstring>
void reverse( std::string* str ) // no need to pass size to this function
{
int start = 0;
int end = str->length() - 1; // get the length of str like this
char* ptrToCharArray = const_cast<char*>( str->c_str() ); // gets the pointer to str's internal buffer
while ( start < end )
{
std::swap( ptrToCharArray[start++], ptrToCharArray[end--] ); // no need to use * operator anymore
}
}
int main()
{
std::string str = "Something";
reverse( &str );
std::cout << "Reversed string: " << str << std::endl;
return 0;
}
Output is:
Reversed string: gnihtemoS
Hopefully, this helps you.
Just need a little bit of change in your code
Change this *str[start++] to (*str).at(start++)
void reverse(string* str, int size)
{
int start = 0;
int end = size - 1;
while(start < end)
{
swap((*str).at(start++),(*str).at(end--));
}
}
int main()
{
string str = "Something";
reverse(&str, str.length());
cout << "Reversed string: " << str << endl;
return 0;
}
Note that there is no need to pass the size of the string as an argument to the function. You can use the member function std::string::size for that purpose as shown below:
Version 1: Passing pointer to string as argument
#include <iostream>
#include <algorithm>
void reverse(std::string *str)
{
int n=(*str).size()-1;//dereference the pointer and use size member function on the resulting string object
for(int i=0;i<((*str).size()/2);i++){
//Using the swap method to switch values at each index
std::swap((*str).at(i),(*str).at(n)); //note this can also be written as std::swap((*str)[i],(*str)[n]);
n = n-1;
}
}
int main()
{
std::string myString = "myString";
reverse(&myString);
std::cout<<"Reversed string is: "<<myString<<std::endl;
return 0;
}
In version 1, *(str) gives us a std::string type object. Next we call size member function on this std::string object. Similarly we can call the std::string::at member function on this std::string object.
Version 2: Passing reference to string as argument
#include <iostream>
#include <algorithm>
void reverse( std::string &str)
{
int n=str.size()-1;
for(int i=0;i<(str.size()/2);i++){
//Using the swap method to switch values at each index
std::swap(str.at(i),str.at(n));
n = n-1;
}
}
int main()
{
std::string myString = "myString";
reverse(myString);
std::cout<<"Reversed string is: "<<myString<<std::endl;
return 0;
}

C++ argument of type "std::string(*)[3][5][30]" is incompatible with parameter of type "std::string *"

I'm working on a code that will take a single user input and split it into five substrings. Partway through, I discovered this error I got when calling the function Split_Input. I've never gotten this before and I feel like there's an easy solution, I just can't put my finger on it. Any help would be appreciated! Thank you in advance!
#include <iostream>
#include <string>
using namespace std;
//This function will take the user input and split it into five substrings
void Split_Input(string *database, int ROWS) {
//------USER INPUT----------
cout << "Enter your first name, last name, age, phone number, and email address. \n";
cout << "Make sure you separate each value with a comma!\n";
string info;
cin >> info;
//------GETTING THE SUBSTRINGS--------
//This value will count each comma and sort the substrings
int column_count = 0;
for (int i = 0; info[i] != '\0'; i++) {
if (info[i] == ',') {
column_count++;
continue;
}
//The i marks the array's position by reference
database[ROWS][column_count][&i] = info[i];
}
}
int main(void)
{
const int COLUMNS = 5, ROWS = 3, CHARS = 30;
string database[ROWS][COLUMNS][CHARS];
Split_Input(database, ROWS);
return 0;
}
The issue which you asked is the type incompability, and error is even tells you what you need to do. So into function Split_Input you need pass a std::string(*)[3][5][30] and you function call should look like this
Split_Input(&database[ROWS][COLUMNS][CHARS], ROWS);
I don't for what the heck you need adress in this line:
database[ROWS][column_count][&i] = info[i];
BTW, you can replace searching comma you can replace with string.find(',').
I understand it is your beginning with C++, so feel free to ask questions.

C++: Constant Reference Parameters

why do we use Constant Reference Parameters in this code
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
// Converts a hex number as a string to decimal
int hex2Dec(const string& hex); // here why we use reference and const it seems we do not change hex in the function body
// Converts a hex character to a decimal value
int hexCharToDecimal(char ch);
int main()
{
// Prompt the user to enter a hex number as a string
cout << "Enter a hex number: ";
string hex;
cin >> hex;
cout << "The decimal value for hex number " << hex
<< " is " << hex2Dec(hex) << endl;
return 0;
}
int hex2Dec(const string& hex)
{
int decimalValue = 0;
for (unsigned i = 0; i < hex.size(); i++)
decimalValue = decimalValue * 16 + hexCharToDecimal(hex[i]);
return decimalValue;
}
int hexCharToDecimal(char ch)
{
ch = toupper(ch); // Change it to uppercase
if (ch >= 'A' && ch <= 'F')
return 10 + ch - 'A';
else // ch is '0', '1', ..., or '9'
return ch - '0';
}
what is the use of calling by reference in this problem ?
in this segment of code
int hex2Dec(const string& hex)
{
int decimalValue = 0;
for (unsigned i = 0; i < hex.size(); i++)
decimalValue = decimalValue * 16 + hexCharToDecimal(hex[i]);
return decimalValue;
}
we do not change the hex.
what is the purpose of const reference in this example and in genral?
The naive solution is to use int hex2Dec(string hex) here. However because function arguments are copied in C++ calling this function would cause a new string to be created for hex, copied from the function argument every time hex2Dec is called. This can lead to needless performance issues, specially if the strings are large.
The solution to this problem is to pass the argument by reference. Using int hex2Dec(string & hex) fixes the first problem, now calling the function never causes a new string to be created. It always refer to whatever string was given.
This introduces a new problem. First, because the argument is a reference, it's possible for the function to change the argument. Because we can see the function implementation, we know it doesn't. But anyone trying to use that function can't know that. Second, because of this, it is not possible to call the function with a const string. The compiler knows it is forbidden to change a const string and it sees that the function doesn't promise not to change it so it will produce an error if you try it. This is very limiting, for example it wouldn't be possible to call the function with a string literal (ex. hex2Dec("test")).
#include <string>
int hex2Dec(std::string& hex);
int main()
{
std::string foo = "foo";
const std::string bar = "bar";
hex2Dec(foo); // Okay
//hex2Dec(bar); Compilation Error
//hex2Dec("baz"); Compilation Error
}
The solution to this new problem is to add const to the argument type : int hex2Dec(const string & hex). The const means that this reference can never be used to modify the argument. Now, users of the function and the compiler both know its safe to use the function with const strings, and the calling the function never copies the argument.
#include <string>
int hex2Dec(const std::string& hex);
int main()
{
std::string foo = "foo";
const std::string bar = "bar";
hex2Dec(foo); // Okay
hex2Dec(bar); // Okay
hex2Dec("baz"); // Okay
}

Function with constant reference as input

I am trying to make a function that takes a constant reference of a string as input and returns the string after each character of the string is rotated 1 place to the right. Using references and pointers still confuses me and I am not sure how to obtain the string from the constant reference.
string rotate(const string &str){
string *uno = &str;
string dos = rotate(uno.rbegin(), uno.rbegin() + 1, uno.rend());
return dos;}
This is what I have got so far but it does not compile. Any tips on how to properly get the string from the constant reference will be appreciated.
You can't perform the rotation in-place without violating the const contract on the parameter, so you should copy the input and return a new string:
string rotate(const string &str){
string uno = str;
rotate(uno.rbegin(), uno.rbegin() + 1, uno.rend());
return uno;
}
Another reasonable option would be to use std::rotate_copy
The line
string* uno = string &str;
makes no sense. I think you mean
string* uno = const_cast<string*>(&str);
You might consider this rotate:
// rotate last char to front
std::string rotate(const std::string& str)
{
return(str[str.size()-1] +
str.substr(0,str.size()-1));
}
// 'abcdefghijklmnopqrstuvwxyz'
// 'zabcdefghijklmnopqrstuvwxy'
You could pass in a string to receive the rotated string, thus avoiding return by value copy.
I passed the string in by pointer, as its clearer at the call site that it's intended to be altered, but it could easily be passed by reference if preferred.
#include <string>
#include <iostream>
#include <algorithm>
void rotate(std::string const& str, std::string* out)
{
*out = str;
std::rotate(out->rbegin(), out->rbegin() + 1, out->rend());
}
int main(int, char**)
{
std::string out;
std::string x = "1234567";
std::cout << x << '\n';
::rotate(x, &out);
std::cout << out << '\n';
}

Convert vector<string> * char to int

I need help in my following code and hope that you can help me through. All I wanted is to pass in INT type to setX() and setY(). However, there is no way for me to convert vector char* to int. Is there alternative to this?
template<class T>
vector<string> Delimiter(T inputString){
int count=0;
char str[inputString.length()];
strcpy(str,inputString.c_str());
char * pch;
vector<string> returnContainer;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,",[]");
while (pch != NULL)
{
returnContainer.push_back(pch);
pch = strtok (NULL, " ,[]");
count++;
}
for(int i=0; i<returnContainer.size(); i++){
cout << "return:" << returnContainer[i] << endl;
}
return returnContainer;
}
//Main()
fileDataAfterFiltered = Delimiter(fileData[i]); // Delimiter (vector<string> type)
point2DObj[point2DCount].setX(fileDataAfterFiltered[1]); // error
point2DObj[point2DCount].setY(fileDataAfterFiltered[2]); // error
//Assn3.cpp:107:59: error: no matching function for call to ‘Point2D::setX(std::basic_string&)’
Delimiter() returns a vector<string> and you give one of these strings to setX() and setY(), but both expect an integer parameter. You must convert the string to int
int x = atoi(fileDataAfterFiltered[1].c_str());
point2DObj[point2DCount].setX(x);
int y = atoi(fileDataAfterFiltered[2].c_str());
point2DObj[point2DCount].setY(y);
But: in C++ array and vector elements start at 0 not 1, so you might want to replace this with fileDataAfterFiltered[0] and fileDataAfterFiltered[1] respectively.
If you are using a C++11 compiler, function std::stoi() will do the trick:
point2DObj[point2DCount].setX(std::stoi(fileDataAfterFiltered[1]));
Otherwise you can use the old atoi():
point2DObj[point2DCount].setX(atoi(fileDataAfterFiltered[1].c_str()));
Aside from this, your code has many other problems, but I hope you can fix them by yourself.
there's plenty of ways of converting string to int. boost::lexical_cast is one which will magically do the conversion you want. Otherwise you can use atoi (if you don't care about errors), or strtol (if you do).
point2DObj[point2DCount].setX(atoi(fileDataAfterFiltered[1].c_str()));
point2DObj[point2DCount].setX(boost::lexical_cast<int>(fileDataAfterFiltered[1]));