How can I get a cstring into a class? - c++

I'm going to using cstring finish the program
now I required to get the name of PokemonWorld from user
and initialize it
But I can't get the cstring from main() into class PokemonWorld
I tried cin >> world.setName and cin >> name; world.setName(name)
both of which failed
class PokemonWorld {
private:
char name[10];
public:
void setName(char x[]) {
*name = x;
};
char* getName(){
return name;
};
};
void main() {
PokemonWorld world;
int number;
char name[10];
cout << "What is the World Name ?" ;
cin >> name;
world.setName(name);
Also I cannot using getName to return the name that assigned into PokemonWorld
Here is the error code:
Error C3867 'PokemonWorld::getName': non-standard syntax; use '&' to create a pointer to member
Should I create PokemonWorld as pointer?

With cstring, you have to use c string manipulator. You definitively can't assign an array to another one. For your issue, use strncpy_s:
void setName(char x[]) {
strncpy_s(name, 10, x, 10);
};
Also, to avoid issue, your getter should be:
const char * const getName() const {
return name;
};
Also, to compare, use strncmp, to concatenate use strncat, ...
Or, because you use c++, use std::string

You need to set the name first. In your main method,
PokemonWorld world;
int number;
char name[10];
cout << "What is the World Name ?" ;
cin >> name;
world.setName(name);
//Then get the name
world.getName(name);

You are not using a cstring (most people who hear "cstring" think of the CString class of the MFC library).
You are using a "C" string, or a raw char pointer. This is bad practice in general, as it involves performing memory management manually, and unless you solve the problems that come with using raw pointers, you will simply have those problems in your code.
setName should be:
void setName(char const * const x)
{
auto length = std::min(std::strlen(x), 9); // only copy up to 9 characters
std::copy_n(x, length, name);
name[length] = '\0';
}
... or (as already pointed out):
strncpy_s(name, 10, x, 10);
getName should be:
char const * const getName() const
{
return name;
}
This code is almost correct:
char name[10];
cout << "What is the World Name ?" ;
cin >> name;
world.setName(name);
... but you should initialize name where you declare it:
char name[10] = { 0 };
Also, what will you do if the user inputs more than 10 characters? In that case the stack of your program will become corrupted.
You could avoid the problem by using a std::string.

Related

Dynamicly setting which parameter to extract

Having structure
struct Person{
Person(int a , int i):age(a),id(i){};
int age;
int id;
}
Is it possible to pass which argument to exctract as argument in function? Something like
int extract( Person * p , param ){
return p -> param;
}
which would return id , if used it like
extract( p , "id" )
and age if i used it like
exctract(p , "age")
Is something like this possible in c++?
You can use pointers to class members.
struct Person{
Person(int a , int i):age(a),id(i){};
int age;
int id;
};
int extract(Person* p, int Person::* param)
{
return p->*param;
}
and you'd use it like this:
extract(p, &Person::id);
demo
You can do it with preprocessor abuse, and more notably, without using string comparisons, which seems like what you want to do.
#include <iostream>
#define extract(p, i) (p->i)
struct Person{
int age;
int id;
};
int main() {
Person p;
p.age = 100;
p.id = 30;
std::cout << extract((&p), id) << '\n' << extract((&p), age) << '\n';
}
Not that I suggest doing this, though.
You can use Map<char*, int>which can do exactly that (but arguably is a bit of owerkill).
Or just plain char[][] and check equality with the parameter in a for loop.

Don't know how to make this compile right: incompatible types in assignment

sorry, I'm not a very advanced programmer, could you guys help me find a solution for this?
class Person
{
private:
char name[50];
double age;
public:
void setName(char []);
void setAge(int);
char* getName();
double getAge();
};
void Person::setAge(int a)
{
Person::age = a;
}
char* Person::getName()
{
return name;
}
double Person::getAge()
{
return age;
}
void Person::setName(char n[])
{
Person::name = n;
}
and it keeps giving me
"[Error] incompatible types in assignment of 'char*' to 'char [50]'"
I want to make this work without using an overloaded assignment operator, please help
You can use strncpy (requires n to be '\0' terminated):
void Person::setName(char n[])
{
strncpy(name, n, sizeof(name)/sizeof(name[0]) - 1);
}
or make name an std::string then your original code will work. Also instead of writing char n[] its better to const char* n as n in your setName function is actually a pointer to first element. Also by making it const you allow to pass string literals to your function.
this is what I did, thanks guys for answering, I appreciate it :D
char *name;
void Person::setName(char n)
{
name = new char[n];
}
Just replace char name[50]; with char *name and it will work just fine..

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.

returning a string from a function that the user inputs

I have been searching around the web for returning a string in a function.
const char *func()
{
const char *s1 = "hello";
return s1;
}
This works if you predefine the string. How do I let the user input a string and return that specific string
const char *func()
{
char s1[313];
cin >> s1;
return s1;
}
I tried the above but it gave the warning
warning: address of stack memory associated with local variable
's1' returned [-Wreturn-stack-address]
return s1;
One easy way to do it would be to use an std::string:
#include <string>
#include <iostream>
std::string func()
{
std::string s1;
std::cin >> s1;
return s1;
}
You can either allocate a character array inside the function or pass an array as an argument to the function.
In the first case you can either use standard class std::string or you will need to allocate the array your self.
For example
std ::string func()
{
std::string s1;
cin >> s1;
return s1;
}
or
char * func()
{
const size_t N = 313;
char *s1 = new char[N];
cin.getline( s1, N );
return s1;
}
in the second case the function can look the following way
char * func( char s1[], size_t n )
{
cin.getline( s1, n );
return s1;
}
and in main it could be called as
int main()
{
const size_t N = 313;
char s1[N];
func( s1, N );
}
The "correct" way of doing this in C++ is to use an std::string, as juanchopanza said, but just FYI, one could achieve this without std::strings via something like this:
char* func() {
char* s1 = new char[313]; // allocate memory on the heap
cin >> s1;
return s1;
}
Though this has the stipulation of requiring the caller to delete[] the result of the function:
char* s = func();
// do stuff with s
delete[] s; // must be called eventually
Don't ever do this in actual C++ code though -- use std::string.

how I can overcome this error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'const char []'

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <cstring>
void initialize(char[],int*);
void input(const char[] ,int&);
void print ( const char*,const int);
void growOlder (const char [], int* );
bool comparePeople(const char* ,const int*,const char*,const int*);
int main(){
char name1[25];
char name2[25];
int age1;
int age2;
initialize (name1,&age1);
initialize (name2,&age2);
print(name1,age1);
print(name2,age2);
input(name1,age1);
input(name2,age2);
print(name1,age1);
print(name2,age2);
growOlder(name2,&age2);
if(comparePeople(name1,&age1,name2,&age2))
cout<<"Both People have the same name and age "<<endl;
return 0;
}
void input(const char name[],int &age)
{
cout<<"Enter a name :";
cin>>name ;
cout<<"Enter an age:";
cin>>age;
cout<<endl;
}
void initialize ( char name[],int *age)
{
name[0]='\0';
*age=0; }
void print ( const char name[],const int age )
{
cout<<"The Value stored in variable name is :"
<<name<<endl
<<"The Value stored in variable age is :"
<<age<<endl<<endl;
}
void growOlder(const char name[],int *age)
{
cout<< name <<" has grown one year older\n\n";
*age++;
}
bool comparePeople (const char *name1,const int *age1,
const char *name2,const int *age2)
{
return(*age1==*age2 && !strcmp(name1,name2));
}
The name parameter of your input() function is a pointer to const char. const means you can't modify it, so if you need to modify it, it needs not to be const.
That said, to really fix it, use std::string wherever you currently use char[]s and char*s and consider returning objects instead of using out-parameters; this will make your code much less error prone and easier to follow and understand.
The symbol '>>' is an operator. The writer of the String class included this operator to only take primitive types and of course the String class type.
You have two options:
Convert the char array to a string
Overload the '>>' operator to take char arrays and output it as you like
Look up overloading operator if you really want to have fun.