#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);
};
Related
I have a class called Person:
class Person {
private:
char name[50];
unsigned int number;
public:
void set_data(const char *newname, unsigned int number) {
*name= *newname; //THE MAIN PROBLEM I WANT TO SOLVE
this->number = number;
}
char* get_name() {
return this->name;
}
unsigned int get_number() {
return this->number;
}
};
I have arrays:
const char *names[] = {"Mark", "Pavel", "Bill", "Jasur", "Jeff"};
int phones[] = { 1234567890, 9876543210, 123321456654, 1998946848479, 1234554321 };
I'm using for loop to set Person members:
Person p;
for (int i = 0; i < 5; i++) {
p.set_data(names[i], phones[i]);
cout << p.get_name() << endl;
}
When I run this, I'm getting wrong output.
Using * the way you are, you are only copying the 1st char into name. You are also not null-terminating name either, which is required by the overloaded operator<< that takes a char* as input.
To copy the entire string, you need to use std::strcpy() (or better, std::strncpy()) instead, eg:
#include <cstring>
void set_data(const char *newname, unsigned int newnumber) {
//std::strcpy(name, newname);
std::strncpy(name, newname, 49);
name[49] = '\0';
number = newnumber;
}
However, since this is C++ and not C, you really should be using std::string instead:
#include <string>
class Person {
private:
std::string name;
unsigned int number;
public:
void set_data(const std::string &newname, unsigned int newnumber) {
name = newname;
number = newnumber;
}
std::string get_name() const {
return name;
}
/* or:
const std::string& get_name() const {
return name;
}
*/
unsigned int get_number() const {
return number;
}
};
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 *);
class test
{
private:
string *firstname;
public:
void setfname(const string fname[])
{
delete[] firstname;
firstname = new string[3];
for (int i = 0; i < 3; i++)
{
firstname[i] = fname[i];
}
}
string* getfname(const string fname[]) const
{
return firstname;
}
};
ok now I know the return function is wrong because it's giving me direct access, how do i set up the function so it doesn't allow it.
This is how I am going to test it:
int main()
{
test t;
string narray[3] = { "Name1", "Name2", "Name3" };
t.setfname(narray);
cout << "\nAfter t.setfname(narray);"
<< "\nf.getfname(narray) follows: ";
cout << t.getfname(narray);
}
I know getfname is wrong, how do I fix it?
In the simplest case, just return a copy of the string instead of a pointer:
string getfname(const string fname[]) const
{
return *firstname;
}
Even better, store a string instead of a pointer to it:
class test
{
private:
string firstname;
...
When I try debugging the code, it runs into the debugging error "c++ Expression: string subscript out of range"
Pretty sure the problem was brought while calling setCode().
How do I fix the code inside setCode()?
#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <list>
using namespace std;
class test
{
private:
string code;
int digit;
public:
//constructor
test(): code(""), digit(0) { }
//copy constructor
test(const test &other):
digit(other.digit)
{
for(unsigned int i=0; i < code.length(); i++)
code[digit] = other.code[digit];
}
//set up the private values
void setCode(const string &temp, const int num);
void setDigit(const int &num);
//return the value of the pointer character
const string &getCode() const;
const unsigned int getDigit() const;
};
const string& test::getCode() const
{
return code;
}
const unsigned int test::getDigit() const
{
return digit;
}
void test::setCode(const string &temp, int num)
{
code[num] = temp[num];
}
void test::setDigit(const int &num)
{
digit = num;
}
int main()
{
string contents = "dfskr-123";
test aisbn;
list<test> simul;
list<test>::iterator testitr;
testitr = simul.begin();
int count = 0;
cout << contents << '\n';
aisbn.setCode(contents, count);
aisbn.setDigit(count);
simul.push_back(aisbn);
count++;
/*for(; testitr !=simul.end(); simul++)
{
cout << testitr->getCode() << "\n";
}*/
}
When you create an instance of the test class, the string inside it is empty. This means that whenever you do e.g. code[something] you will be out of range. It doesn't matter what the index is.
You either need to set the string to a certain length from the start, and make sure that the index is within the range. Or to make sure that the index is within range by dynamically extending the string when needed.
You have to make sure that when this statement executes:
code[num] = temp[num];
both code and temp are at least of size num + 1.
I have made a class String which has two private members int length and a character pointer.
There are two constructors which initialize these members.
My question why s1.print() is not working in my code?
#include <iostream>
#include <string.h>
using namespace std;
class String {
int length;
char * ptr;
public:
String(int N, char s[]) {
ptr = new char[N];
strcpy(s, ptr);
}
String(int N) {
ptr = new char[N];
}
String concat(String s2) {
String result(s2.length + length, strcat(ptr, s2.ptr));
}
void print(void) {
cout << ptr << endl;
}
};
int main() {
char temp[50];
cin >> temp;
String s1(strlen(temp) + 1, temp);
//String s2(strlen(temp)+1, temp);
s1.print();
//s1.concat(s2);
//s1.print();
return 0;
}
In order to print the char* you need to cast it to string and than print.
Another thing I suggest that your array size will be N + 1 and add a NULL-terminate at ptr[N] = '\0'