Animal class in C++ - c++

I want to make an Animal class in c++ using string. But it look like by using string it show so much of error and doesn't get resolve. Can someone help me what is wrong in my code?
#include<iostream>
using namespace std;
class Animal {
char str1[100], str2[100], str3[100];
public :
void setData(char a, char b, char c);
void getData() {
cout<<"The type of animal is "<<str1[100]<<endl;
cout<<"The name of "<<str1[100]<<" is "<<str2[100]<<endl;
cout<<" "<<str1[100]<<" "<<str3[100]<<endl;
}
void Animal :: setData(char a, char b, char c) {
str1[100] = a;
str2[100] = b;
str3[100] = c;
}
int main() {
Animal isha;
isha.setData('D', 'T', 'B');
isha.getData();
return 0;
}

You have undefined behavior in your program because you're going out of bounds of the array str1, str2 and str3 in addition to syntax errors as explained below:
Problem 1
You're missing the closing brace } and a semicolon ; for the class. To solve this add }; at the end of the class definition as shown below.
Problem 2
Even after fixing the syntax error, you will have undefined behavior in your program because you're going out of bounds of the arrays str1, str2 and str3 when you wrote:
void getData() {
//----------------------------------vvvvvvvvv---------------->undefined behavior
cout<<"The type of animal is "<<str1[100]<<endl;
//------------------------vvvvvvvvv----------vvvvvvvvv------->undefined behavior
cout<<"The name of "<<str1[100]<<" is "<<str2[100]<<endl;
//-------------vvvvvvvvv-------vvvvvvvvv--------------------->undefined behavior
cout<<" "<<str1[100]<<" "<<str3[100]<<endl;
}
void Animal :: setData(char a, char b, char c) {
str1[100] = a; //undefined behavior
str2[100] = b;//undefined behavior
str3[100] = c;//undefined behavior
}
Solution
Better would be to use std::string instead of built in arrays and make sure that you're don't go out of bounds of the array(in case arrays are used) as shown below. The code given is a demonstration of how to fix the issues.
class Animal {
std::string str1, str2, str3;
public :
void setData(std::string a, std::string b, std::string c);
void getData() {
std::cout<<"The type of animal is "<<str1<<std::endl;
std::cout<<"The name of "<<str1<<" is "<<str2<<std::endl;
std::cout<<" "<<str1<<" "<<str3<<std::endl;
}
};
void Animal :: setData(std::string a, std::string b, std::string c) {
str1= a;
str2= b;
str3= c;
}
int main() {
Animal isha;
isha.setData("D", "T", "B");
isha.getData();
return 0;
}
One of the reasons why using std::string is better here in your example is that using char arrays is that while using char arrays in your original example, you were wasting space as each of those array were of length 100. By using std::string that wastage of space in longer there. Additionally, elements can be added and removed from a std::string and so this make the program more flexible.

Related

Why is member function call "ambiguous"?

Why is my overloaded member function only "ambiguous" as a char and not an int and string?
I'm trying to create a one-code path for my Char class by funneling code through an overloaded equals() function. It works fine when I use equals as an int and string but is ambiguous as a char.
class Char
{
private:
char cData;
int iData;
string sData;
public:
//Mutators:
void equals(char c);
void equals(int c);
void equals(string c);
//Constructors:
Char(char c);
Char(int c);
Char(string c);
};
void Char::equals(char c)
{
cData = c;
}
void Char::equals(int c)
{
iData = c;
}
void Char::equals(string c)
{
sData = c;
}
Char::Char(char c)
{
this->equals(c); //Call to member function 'equals' is ambiguous
}
Char::Char(int c)
{
this->equals(c);
}
Char::Char(string c)
{
this->equals(c);
}
The error only happens for char, which is confusing since string works fine. I expected it to work for all of them since that's been the case so far.
It's ambiguous because if you do
Char c(42);
The compiler does not know whether it should call the char or int constructor. Both are an equally good match.
The same goes for equals(123);. Again, both the char and int overloads match and the compiler cannot tell which one you intend to call.
you can use a single equal method to accept a char or an int. like
void euqals(unsigned int c_i);

C++ text argument to constructor

cont = cont;
I don't know how to convert cont to cont type pointer.
If I do like this : this->cont = (char*)cont;
In deconstructor I have exception error.
So is it good to convert const char to char* or I need to do better (but how?) ?
And I have to have dynamic allocate.
#include "pch.h"
#include <iostream>
#include <stdio.h>
using namespace std;
class Matrix {
private:
int x;
char *cont;
public:
Matrix(){
cout << "aa";
}
Matrix(const char *cont) {
this->cont = cont;
}
~Matrix() {
delete cont;
}
};
int main()
{
Matrix("__TEXT__");
system("pause");
return 0;
}
this->cont = cont;
Is "wrong", as in, it doesn't actually copy the data; that's also why delete in your destructor if failing. Your answer mentions "I have to have dynamic allocate.", so I presume that's what you actually wanted. In this case, simply use std::string:
class Matrix {
private:
int x;
std::string cont; // <--- changed type
public:
Matrix(){
cout << "aa";
}
Matrix(const char *cont)
: cont(cont) { // <--- this actually copies
}
};
first you have to allocate space for a pointer to char using new .
And in the destructor deallocate that space " delete [] cont " instead of "delete cont" .
but it will be a good choice to use std::string instead of char []

cannot copy string to an character array

#include<iostream>
class ravi
{
private:
char a[10],char b[10];
public:
void setdata(char x[10],char y[10])
{
a = x; b = y;
}
void show()
{
std::cout << a << b;
}
};
int main()
{
ravi r;
r.setdata("text","copied");
r.show();
}
i am trying to copy the strings "text" "copied" to x and y and i am getting an error that "incompatible types in assignment from char* to char" .can someone tell me what is wrong with my code.
Strings in C++ are std::string. You are using char arrays, aka C-strings, NUL terminated strings, etc. which are harder to manipulate.
Simply by replacing the type of a and b (and a minor improvement on the arguments of setdata, you get something working, plus some useful features of string:
#include <string>
class ravi
{
std::string a;
std::string b;
public:
void setdata(const char* x, const char* y)
{
a = x;
b = y;
}
void show()
{
std::cout << a << b;
}
};
If this is possible (regarding the API of ravi), try and use std::string const& in lieu of const char*:
void setdata(std::string const& x, std::string const& y)
With C++17, you'd better use std::string_view in lieu of const char* for argument types:
void setdata(std::string_view x, std::string_view y)
Arrays do not have the copy assignment operator. So these statements
a=x;b=y;
are invalid.
You should use standard C function strcpy or strncpy declared in the header <cstring> to copy character arrays. Also string literals in C++ have types of constant character arrays. So the parameters of the member function setdata should be declared with the qualifier const.
void setdata( const char x[], const char y[] )
{
strncpy( a, x, sizeof( a ) );
a[sizeof( a ) - 1] = '\0';
strncpy( b, x, sizeof( b ) );
b[sizeof( b ) - 1] = '\0';
}
Take into account that this statement is invalid
char a[10],char b[10];
Either you should write
char a[10]; char b[10];
or
char a[10], b[10];
Use the strcpy function from string.h:
#include <string.h>
void setdata(char x[10],char y[10])
{
strcpy(a,x);
strcpy(b,y);
}

c++ array to array assignment

I wrote the following employee class:
#include<iostream>
#include<string>
using namespace std;
class employee
{
private:
int id;
int salaries[12];
int annualS;
string name;
public:
employee(int id2, string name2, int array[12])
{
id = id2;
name=name2;
salaries = array; //here where the error occurred.
}
~employee()
{
cout<<"Object Destructed";
}
employee()
{
id = 0;
name="Mhammad";
}
int annulalSalary()
{
for( int i=0; i<12; i++)
{
annualS+=salaries[i];
}
return annualS;
}
int tax()
{
return (annualS*10/100);
}
};
void main()
{
int salaries[12];
for(int i=0; i<12; i++)
{
cin>>salaries[i];
}
employee Mohammad(10,"Mohammad",salaries);
cout<< Mohammad.annulalSalary();
cout<< Mohammad.tax();
}
...but when I compile it the, compiler returns the following error:
cannot convert from 'int []' to 'int [12]'
Could anyone help me solve this problem?
you can not copy an entire array just using = operator in c++. you have two options.
overload = operator
or
use a for loop like this to copy each element of one array to another
for(int i=0 ; i<12 ; i++)
salaries[i]=array[i];
on a different note don't use magic numbers like 12 in your code.
Instead of a C array, use the C++ std::array<>, like this:
class employee {
//...
std::array<int, 12> salaries;
//...
};
and of course you'd have to include <array> too. And declare the constructor like this:
employee(int id2, string name2, std::array<int, 12> const & array)
{
//...
}
(or drop the const & if you're not sure what they are or don't need them.)
You can not copy arrays by assignment. You need to copy each element individually. Use std::copy.
std::copy(array, array+12, salaries);
Or use std::vector<int> or std::array<int, 12> as suggested by Borgleader which does copy by assignment.
Use the vector class!
But to solve your problem :
int salaries[12] should be int* salaries
employee(int id2, string name2, int array[12]) should be employee(int id2, string name2, int* array)
but then you might a problems of referencing things outside the allocated memory and segfault.
USE VECTORS!

c++ char array output in class functions

I am a real c++ beginner and I have a problem with my char array output in a c++ excerise. I was asked to transform a certain UML class in to c++ and generate an working output with the parameters given in main. Here ist the code:
#include <iostream>
#include <stdlib.h>
/*My class defintion book*/
class Book
{ protected:
long int number;
char author[25];
int year;
bool lent;
void setLent(bool x);
bool getLent();
public:
Book(long int n, char a[25], int j, bool x);
long int getNr();
int getYear();
void print();
};
/*Method definition Book*/
Book::Book(long int n, char a[25], int j, bool x)
{number=n;
author=a;
year=j;
lent=x;}
long int Book::getNr()
{return number; }
int Book::getYear()
{return year;}
void Book::setLent(bool x)
{lent=x;}
bool Book::getLent()
{return lent;}
void Book::print()
{
std::cout << "Book Nr: " << number << std::endl;
std::cout << "Author: " << author << std::endl;
std::cout << "Year: " << year << std::endl;
if (lent==0)
std::cout << "Lent [yes/no]: no" << std::endl;
else
std::cout << "Lent [yes/no]: yes" << std::endl;
}
/*MAIN*/
int main()
{
Book b1(123456, "test", 2014, false);
b1.print();
system("pause");
return 0;
This is my output:
Book Nr: 123456
Author: b<Vv-[[vóYA
Year: 2014
Lent [yes/no]: no
Press any key to continue...
As you can see all outputs work except for the "Author". There I am getting crap. Note that I have to use char as type. since it is given in the UML class I had to transform into c++.
I really searched everywhere. But didn't find the correct solution. I have the feeling it will be a very simple one...
Thanks in advance for your help!
The reason this doesn't work is that you're assigning your pointer author to another pointer a, which then goes out of scope... so you're left with author pointing to some garbage. If you want to stick with character arrays, you'll have to copy all the data that a points to:
strcpy(author, a);
But since it's C++, you should just use strings, which are easier to deal with:
class Book {
...
std::string author;
....
};
Book::Book(long int n, const std::string& a, int j, bool x)
: author(a), ...
{ }
You are printing out uninitialized data.
Make author a string
#include <string>
class Book
{ protected:
long int number;
std::string author;
int year;
bool lent;
and make the argument to the constructor a string as well
Book::Book(long int n, const std::string& a, int j, bool x)
Arrays of characters are not as flexible as std::strings. they are just chunks of data. If you want to use strings then use std::string instead.
Also, use an initializer list in C++ constructors, not java style
Book::Book(long int n, const std::string &a, int j, bool x)
: number(n),
author(a),
year(j),
lent(x)
{ }
There are two bugs in your code:
Book::Book(long int n, const char a[25], int j, bool x)
{
number=n;
strncpy(author, a, 25); // author = a; doesn't work! shouldn't compile either...
year=j;
lent=x;
}
First: The variable author is a pointer to a zero terminated string. You can use strcpy() to copy this string. Therefore you need to #include <memory.h. But you need to be sure that the string -is- really zero-terminated and fits into your target variable! Else you'll overwrite other memory regions next to the target variable, which is also called a buffer overflow! Better use strncpy(target, source, maxlength); which avoids this problem.
Second: Your parameter a should be "const" as you want to be able to call it with a string constant like in Book b1(123456, "test", 2014, false); where "test" is a constant!
As others already suggested you should use std::string instead of a[25]. C-Strings are "C" and not "C++" and you should try to avoid them. C-Strings can introduce a lot of bugs into your code and enable buffer overflows (=security problems), too. Also they are more complicated to handle. You need to #include <string> to use them.