I'm working on a project for class, but keep getting the error: no instance of overloaded function matches argument list. It is referencing my String classes. What I am trying to do is create a Copy, Concat and Count functions with out using the string class. Any help would be greatly appreciated.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
class String
{
private:
char str[100];
char cpy[100];
public:
static const char NULLCHAR = '\0';
String()
{
str[0] = NULLCHAR;
cpy[0] = NULLCHAR;
}
String(char* orig, char* cpy)
{
Copy(orig, cpy);
}
void Display()
{
cout << str << endl;
}
void Copy(char* orig, char* dest)
{
while (*orig != '\0') {
*dest++ = *orig++;
}
*dest = '\0';
}
void Copy(String& orig, String& dest)
{
Copy(orig.str, dest.cpy);
}
void Concat(char* orig, char* cpy)
{
while (*orig)
orig++;
while (*cpy)
{
*orig = *cpy;
cpy++;
orig++;
}
*orig = '\0';
}
void Concat(String& orig, String& cpy)
{
Concat(orig.str, cpy.cpy);
}
int Length(char* orig)
{
int c = 0;
while (*orig != '\0')
{
c++;
*orig++;
}
printf("Length of string is=%d\n", c);
return(c);
}
};
int main()
{
String s;
s.Copy("Hello");
s.Display();
s.Concat(" there");
s.Display();
String s1 = "Howdy";
String s2 = " there";
String s3;
String s4("This String built by constructor");
s3.Copy(s1);
s3.Display();
s3.Concat(s2);
s3.Display();
s4.Display();
system("pause");
return 0;
}
It looks like your Copy and Concat functions each take two parameters, yet you pass them both a single parameter. If you want to copy them into a String object, your code should look more like:
String Copy(char* orig)
{
// Same copy logic you have,
// except copy into "*this"
}
As the error message says, There is no version of the constructor for your String class that takes a single parameter. You have a default constructor and one that takes two parameters.
You need to define one which takes a single parameter and initializes the str
String s4("This String built by constructor");
this statement needs construction function
String(char *);
Related
I am doing a custom string class in C++. However, when I debugged my code, the system said that:
Error E0415:no suitable constructor exists to convert from "const char" to "string"
Here is my header file where my custom string class is defined:
#ifndef _STRING
#define _STRING
#include <iostream>
class string {
private:
char* s = nullptr;
unsigned int size = 0;
public:
string();
~string() { delete s; };
void operator=(const char*);
friend std::ostream& operator<<(std::ostream&, string&);
};
#endif
string::string()
: s{ nullptr }
{
s = new char[1];
s[0] = '\0';
}
void string::operator=(const char* source)
{
if (source == nullptr) {
s = new char[1];
s[0] = '\0';
}
else {
size = strlen(source) + 1;
s = new char[size];
for (int k = 1; k < (strlen(source) + 1); k++) {
s[k] = source[k];
}
}
}
std::ostream& operator<<(std::ostream& output, string& result)
{
output << result.s;
return output;
}
And here is my main file which I tried to comply:
#include "custom_string.h"
int main()
{
string a;
a = "testfile";
std::cout << a;
system("pause");
return 1;
}
As you can see, I have declared a constructor to convert const char to my custom string by overloading assignment operator. However, there should be something wrong in my code and I could not find out it. Please help me and thank you
Thanks everyone, I have done to fix it. As it turned out, I have to declare one more constructor to covert between my custom string and const char. That is something like this:
string::string(const string& t){}
string& string::operator=(const char&source){}
I was just experimenting and making my own string class. (Mainly because there is some stuff I wanted to build in custom methods like "toBase64" etc. Anyways, I was wondering how you could access the private member of char* when you use &String[0].
I thought you could use operator-overloading but I currently only have it as String[0] returns the char*. (I know & is the pointer operator).
String.h
namespace CoffeeBeans
{
class _declspec(dllexport) Coffee_String
{
char* String;
int StringLength;
public:
Coffee_String();
Coffee_String(LPCSTR CString);
LPSTR operator[](int);
~Coffee_String();
};
}
String.cpp
#include "stdafx.h"
#include "String.h"
#include <Windows.h>
CoffeeBeans::Coffee_String::Coffee_String() {
this->String = nullptr;
this->StringLength = 0;
}
CoffeeBeans::Coffee_String::~Coffee_String() {
if (String != nullptr) {
delete[] this->String;
this->String = nullptr;
this->StringLength = 0;
}
}
CoffeeBeans::Coffee_String::Coffee_String(LPCSTR CString) {
int StringLength = strlen(CString) + 1;
this->String = new char[StringLength]();
this->StringLength = StringLength - 1;
memcpy_s(this->String, StringLength, CString, StringLength);
}
LPSTR CoffeeBeans::Coffee_String::operator[](int)
{
return this->String;
}
Main.cpp
case WM_CREATE:{
CoffeeBeans::Coffee_String String("Test");
//I want to be able to do
//strcpy_s(&String[0], 3, "hi"); //Copy "hi" into the private variable char*String.
//I know this isn't a practical use, I wanted quick example (I would really pass it to recv (WinSock2))
MessageBeep(0);
break;
}
Your operator[] is returning the wrong value. In order for &String[index] to access the correct memory address, operator[] needs to return a reference to the character at the specified index, not return the string pointer itself, as you are currently doing.
If you look at the actual declaration of std::string::operator[], you will see that it returns a std::string::reference (aka char &) or std::string::const_reference (aka const char &) (depending on whether it is being called on a non-const or const std::string object).
Try something more like this:
String.h
namespace CoffeeBeans
{
class _declspec(dllexport) Coffee_String
{
char* String;
int StringLength;
public:
Coffee_String();
Coffee_String(const Coffee_String &src);
Coffee_String(const char *src);
~Coffee_String();
char& operator[](int index);
const char& operator[](int index) const;
Coffee_String& operator=(const Coffee_String &rhs);
};
};
String.cpp
#include "stdafx.h"
#include "String.h"
#include <algorithm>
#include <cstring>
CoffeeBeans::Coffee_String::Coffee_String() {
String = nullptr;
StringLength = 0;
}
CoffeeBeans::Coffee_String::Coffee_String(const CoffeeBeans::Coffee_String &src) {
StringLength = src.StringLength;
String = new char[StringLength+1];
std::copy(src.String, src.String+StringLength, String);
String[StringLength] = 0;
}
CoffeeBeans::Coffee_String::Coffee_String(const char *src) {
StringLength = std::strlen(str);
String = new char[StringLength+1];
std::copy(src, src+StringLength, String);
String[StringLength] = 0;
}
CoffeeBeans::Coffee_String::~Coffee_String() {
delete[] String;
String = nullptr;
StringLength = 0;
}
char& CoffeeBeans::Coffee_String::operator[](int index)
{
return String[index];
}
const char& CoffeeBeans::Coffee_String::operator[](int index) const
{
return String[index];
}
CoffeeBeans::Coffee_String& CoffeeBeans::Coffee_String::operator=(const CoffeeBeans::Coffee_String &rhs);
{
Coffee_String temp(rhs);
std::swap(String, temp.String);
std::swap(StringLength, temp.String);
return *this;
}
Main.cpp
case WM_CREATE: {
CoffeeBeans::Coffee_String String("Test");
strcpy_s(&String[0], 3, "hi"); //Copy "hi" into the private variable char *String...
// note that the content of String will become "hi\0t\0", not "hi\0"
// and StringLength will still be 4...
MessageBeep(0);
break;
}
I have class Pstring
class Pstring
{
private:
string palindrome;
public:
Pstring() { palindrome = ""; }
Pstring(string pal) { setString(pal); }
void setString(string pal) { palindrome = pal; }
string getPal() const { return palindrome; }
};
an object in my main method Pstring palindrome(palin) defined by
string palin = "";
cout << "Enter a palindrome:\n";
getline(cin, palin);
Pstring palindrome(palin);
and a current test method bool isPalindrome(string pal)defined as
bool isPalindrome(string pal)
{
bool flag;
cout << "Do I have access to this?";
cout << pal;
//code goes here to check for palindrome, return bool
}
I want to have my Pstring class object palindrome use the method isPalindrome in main, but when I try and invoke the method by using palindrome.isPalinedrome(palin); it doesn't seem to have access to the method.
What can I do to allow a method outside the class to be used by a class object in main?
You don't have a isPalinedrome() method defined in the Pstring class, so you can't call it as palindrome.isPalinedrome() in your main code.
Instead of having Pstring try to call a function in your main code, you should move the palindrome logic into Pstring, and then the main code can ask Pstring when needed.
Try this:
class Pstring
{
private:
string value;
public:
Pstring() { }
Pstring(const string &s) { setString(s); }
void setString(const string &s) { value = s; }
string getString() const { return value; }
// add this...
bool isPalindrome() const {
//code goes here to check value for palindrome, return bool
}
};
Then your main code can do this:
bool isPalindrome(const string &value)
{
Pstring palindrome(value);
return palindrome.isPalindrome();
// or simply:
// return Pstring(value).isPalindrome();
}
int main()
{
string palin;
cout << "Enter a palindrome:\n";
getline(cin, palin);
if (isPalindrome(palin)) {
// do something ...
} else {
// do something else...
}
return 0;
}
Or this:
int main()
{
string palin;
cout << "Enter a palindrome:\n";
getline(cin, palin);
Pstring palindrome(palin);
if (palindrome.isPalindrome()) {
// do something ...
} else {
// do something else...
}
return 0;
}
You should add your test method into the class:
class Pstring
{
private:
string palindrome;
public:
// you don't need to initialize palindrome = "" (it's initialized by default)
Pstring() {}
// always pass strings as const reference unless you have
// special reason to do it another way...
Pstring(const string& pal) { setString(pal); }
void setString(const string& pal) { palindrome = pal; }
string getPal() const { return palindrome; }
bool isPalindrome() const // you don't have to pass string
{
bool flag;
cout << "Do I have access to this?";
cout << palindrome; // please note this
//code goes here to check for palindrome, return bool
}
};
And also please note the typo:
palindrome.isPalinedrome(palin);
You can use function pointer to implement it:
declare class:
class Pstring{
private:
string palindrome;
public:
Pstring() { palindrome = ""; }
Pstring(string pal) { setString(pal); }
void setString(string pal) { palindrome = pal; }
string getPal() const { return palindrome; }
//add a function pointer member:
bool(*isPalindrome) (string);
};
then define function:
bool isPalindrome(string pal)
{
bool flag;
cout << "Do I have access to this?";
cout << pal;
//code goes here to check for palindrome, return bool
return true;
}
now you can write code in main function:
string palin = "";
cout << "Enter a palindrome:\n";
getline(cin, palin);
Pstring palindrome(palin);
palindrome.isPalindrome = isPalindrome;//bind function
you can use the function by the object now:
palindrome.isPalindrome(palin);
Sorry. what's the point to create this class? the only thing you need is the helper function isPalindrome(const std::string&). If you need some kinda scope protection, put it into a namespace may look better
Sorry but I have to say you are just make things complicated.
C++ is not java. If you don't use it, you should not pay for it.
#include <iostream>
#include <string>
using namespace std;
class String {
public:
String (){
//default
value = 0;
name = "noname";
}
String (int x){
setValue(x);
}
String (string y){
setName(y);
}
String (int x ,string y) {
setValue(x);
setName(y);
}
void setValue(int x){
value = x;
}
void setName(string y){
name = y;
}
int getValue(){
return value;
}
string getName(){
return name;
}
int Compare (const char* name1,const char* name2){
const char* n1 = name1;
const char* n2 = name2;
if (strcmp(n1, n2) != 0)
cout <<"test"<<endl;
};
private:
int value;
string name;
const char* n1;
const char* n2;
};
int main ()
{
string str1 ("abcd");
string str2 ("bbbb");
int Compare("abcd", "bbbb");
//String coin1(1,"Penny");
//cout<<"Coin 1 is a "<<coin1.getName()<<" and its worth $"<<coin1.getValue()<<endl;
//String coin2(10,"Dime");
//cout<<"Coin 2 is a "<<coin2.getName()<<" and its worth $"<<coin2.getValue()<<endl;
return 0;
}
I am probably going about this completely wrong but I can't think of any way else to do it.I'm trying to make a strcmp that allows the comparison of the String object to another String object or to a āCā type string but I seem to be doing it wrong.
Because you're not instantiating your String object.
Try with the following main()
int main ()
{
String str1 ("abcd"); // create an instance of String class
String str2 ("bbbb"); // create another
printf("%i", str1.Compare("abcd", "bbbb"));
printf("%i", str2.Compare("abcd", "bbbb"));
return 0;
}
You can also make your Compare() method to work with the instanced string instead, so:
int Compare (const char* nameOther)
{
const char* n1 = name.c_str();
const char* n2 = nameOther;
int result = strcmp(n1, n2);
if (result != 0)
cout <<"not equal"<<endl;
else
cout <<"equal"<<endl;
return result; // you forgot the 'return' at Compare().
};
Then you can do:
int main ()
{
String str1 ("abcd"); // create an instance of String class
String str2 ("bbbb"); // create another
printf("%i", str1.Compare("abcd"));
printf("%i", str2.Compare("abcd"));
return 0;
}
After you tested it, you can remove the unnecessary code from Compare():
int Compare (const char* nameOther)
{
return strcmp(name.c_str(), nameOther);
};
I have this C++ class:
class Test
{
private:
string _string;
public:
Test()
{
}
Test(const char *s)
{
Test((string)s);
}
Test(string s)
{
_string = s;
}
operator const char *()
{
return _string.c_str();
}
operator string()
{
return _string;
}
};
If I use this code in main "1234" is printed to the console:
int main()
{
Test test = string("1234");
string s = test;
cout << s << endl;
return 0;
}
But with this, nothing is printed:
int main()
{
Test test = "1234"; // Only change
string s = test;
cout << s << endl;
return 0;
}
The only difference is which constructor is called. It apperas that the _string variable is a default string instance with the value "" but I don't see how that could have happend. I thought that since _string is on the stack, the assignment I do is safe.
This
Test(const char *s)
{
Test((string)s);
}
does not chain the constructors. It just creates a temporary object in the body of the function. What you need is:
Test(const char *s) : Test(string(s))
{
}