Passing values to arrays in a class (C++) - c++

Trying to learn C++ and came across OOP. I don
t grasp how strncpy(m_strName, strName, 25); works. Isn't this a function? Where is it calling from? I see that it is calling m_strName by pointing through *strName, but how are the values being passed here?
source: program tutorial
#include <iostream>
class Employee
{
public:
char m_strName[25];
int m_nID;
double m_dWage;
// Set the employee information
void SetInfo(char *strName, int nID, double dWage)
{
strncpy(m_strName, strName, 25);
m_nID = nID;
m_dWage = dWage;
}
// Print employee information to the screen
void Print()
{
using namespace std;
cout << "Name: " << m_strName << " Id: " <<
m_nID << " Wage: $" << m_dWage << endl;
}
};
int main()
{
// Declare two employees
Employee cAlex;
cAlex.SetInfo("Alex", 1, 25.00);
Employee cJoe;
cJoe.SetInfo("Joe", 2, 22.25);
// Print out the employee information
cAlex.Print();
cJoe.Print();
return 0;
}

char * strncpy ( char * destination, const char * source, size_t num )
Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.
strncpy(m_strName, strName, 25); will copy 25 characters from strName to m_strName. This function resides in the cstring header file. You will have to include this file in order to use this function.
If you understand this, you will realise that most of your questions don't make sense.

Related

C++ how to put items in an array that is in a class

So I have a program that has a class that represents a player (also called player). The player needs to have a name, password, amount of experience, a position, and an inventory of four items. The program needs to create three (hardcoded) players each with a name, password, experience amount, position, and an inventory of four items. I have it mostly done except one thing, the inventory array. I have it partially set up with a setInv and getInv to both set and get the inventory, but I'm uncertain on how to use getInv to put items into the inventory so I can use getInv to display it. I tried putting an already filled array in the class but the display outputs none of the items. I also tried playerOne("a"); and playerOne.setInv() = "a"; to but both fail. With the first giving me the error of "too many arguments in function call".
I'm also getting the errors The second one give me two errors of "Index '4' is out of valid index range '0' to '3' for possibly stack allocated buffer 'inv'." and "Reading invalid data from 'inv': the readable size is '112' bytes, but '140' bytes may be read."
I'm very new to C++ and would appreciate any help, thank you!
#pragma warning(disable: 4996)
#include<string>
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
//player class
class player {
public:
//name
void setName(string name) {
this->name = name;
} //setName end
string getName() {
return name;
} //getName end
//password
void setPass(string pass) {
this->pass = pass;
} //setPass end
string getPass() {
return pass;
} //getPass end
//experience
void setXP(int xp) {
this->xp = xp;
} //setXP end
int getXP() {
return xp;
} //getXP end
//position
void setPosX(int xPos) {
this->xPos = xPos;
} //setPosX end
void setPosY(int yPos) {
this->yPos = yPos;
} //setPosY end
int getPosX() {
return xPos;
} //getPosX end
int getPosY() {
return yPos;
} //getPosY end
//inventory
string setInv() {
string inv[4];
this->inv = inv[4];
} //setInv end
string getInv() {
return inv;
} //getInv end
void display();
private:
string name;
string pass;
string inv;
int xp = 0;
int xPos = 0;
int yPos = 0;
}; //class end
void player::display() {
//playerOne output
cout << "Player Info - \n";
cout << "Name: " << getName() << "\n";
cout << "Password: " << getPass() << "\n";
cout << "Experience: " << getXP() << "\n";
cout << "Position: " << getPosX() << ", " << getPosY() << "\n";
cout << "Inventory: ";
for (int i = 0; i < 4; i++) {
getInv();
cout << "\n\n";
} //for end
}
int main()
{
//playerOne
player playerOne;
playerOne.setName("Porcupixel");
playerOne.setPass("PokeHerFace2008");
playerOne.setXP(1477);
playerOne.setPosX(16884);
playerOne.setPosY(10950);
//playerTwo
player playerTwo;
playerTwo.setName("Commandroid");
playerTwo.setPass("RodgerRodger00110001");
playerTwo.setXP(73721);
playerTwo.setPosX(6620);
playerTwo.setPosY(36783);
//playerThree
player playerThree;
playerThree.setName("BumbleBeast");
playerThree.setPass("AutoBotsRule7");
playerThree.setXP(20641);
playerThree.setPosX(15128);
playerThree.setPosY(46976);
playerOne.display();
playerTwo.display();
playerThree.display();
return 0;
} //main end
All right, first for your inventory set up, you could do it in a bunch of diverse ways, to begin within your 'setInv' function you are not receiving parameters which is weird since what are you trying to initialize your inventory with? You could initialize all values passing in an array of strings if that makes sense, also from what I gather from your getInv function it looks like you're trying to store the contents of your array of strings in your private var 'inv' however you might be failing to do this since it is only a string and not an array of string, meaning it can only store ONE string or object.
Answering your question more specifically, your 'getInv' is not returning anything because you are not storing anything into your string to begin with:
Just to explain a little bit more.
string setInv() {
string inv[4];
this->inv = inv[4];
} //setInv end
In this code, you are declaring a new array of strings of size 4, then saying that inv is equal to inv[4] which is never initialized therefore you're not storing anything, anyway as I explained earlier it doesn't look like the right way to do what you're trying to!

C++ program has syntax errors, using modules for first time

// Function displays course information
// instructor defaults to Staff
// enrollment defualts to 30
// main() demonstrates function can be called three ways
#include<iostream>
using namespace std;
int main()
{
void displayCourseInfo(char, char* = "Staff", int = 30);
displayCourseInfo("ENG101");
displayCourseInfo("PSY151", "Bossert");
displayCourseInfo("CIS200", "Edwards", 24);
return 0;
}
void displayCourseInfo(char course, char* instructor, int enrollment)
{ cout << course << " taught by " << instructor <<
" enrollment " << enrollment << endl;
}
When I try to run this code I get
this error message. It says that I cannot convert *const char to char.
Thank you for your time and help.
String literals in C++ (opposite to C) have types of constant character arrays. For example the string literal "Staff" has the type const char [6].
Used in expressions array designators with rare exceptions are converted to pointers to their first elements. So the string literal "Staff" used as an argument is converted to a pointer of the type const char *.
The first parameter of the function displayCourseInfo is declared as having the type char while you are trying to pass a string literal as an argument.
A valid program can look the following way
// Function displays course information
// instructor defaults to Staff
// enrollment defualts to 30
// main() demonstrates function can be called three ways
#include<iostream>
using namespace std;
int main()
{
void displayCourseInfo( const char *, const char * = "Staff", int = 30 );
displayCourseInfo("ENG101");
displayCourseInfo("PSY151", "Bossert");
displayCourseInfo("CIS200", "Edwards", 24);
return 0;
}
void displayCourseInfo( const char *course, const char *instructor, int enrollment)
{
cout << course << " taught by " << instructor
<< " enrollment " << enrollment << endl;
}
Its output is
ENG101 taught by Staff enrollment 30
PSY151 taught by Bossert enrollment 30
CIS200 taught by Edwards enrollment 24
This happens because "test in quotes" is by default const char*.
Values with const in their declaration cannot be changed.
You can't pass const variable to function that takes non-const parameters.
You could just make function's parameters const:
#include<iostream>
using namespace std;
void displayCourseInfo(const char *);
void displayCourseInfo(const char *, const char *);
void displayCourseInfo(const char *, const char *, const int);
int main() {
displayCourseInfo("ENG101");
displayCourseInfo("PSY151", "Bossert");
displayCourseInfo("CIS200", "Edwards", 24);
return 0;
}
void displayCourseInfo(const char *course, const char *instructor) {
cout << course << " taught by " << instructor <<
" enrollment " << 30 << endl;
}
void displayCourseInfo(const char *course) {
cout << course << " taught by " << "Staff" <<
" enrollment " << 30 << endl;
}
void displayCourseInfo(const char *course, const char *instructor, const int enrollment) {
cout << course << " taught by " << instructor <<
" enrollment " << enrollment << endl;
}

Passing array of strings to a function

I am trying to create a program that uses class, arrays, and functions to show information about two students(Name, id#, classes registered). The part I am struggling with is passing arrays to a function. How do I do that?
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
class Student // Student class declaration.
{
private:
string name;
int id;
string classes;
int arraySize;
public:
void setName(string n)
{
name = n;
}
void setId(int i)
{
id = i;
}
void setClasses(string c, int num)
{
classes = c;
arraySize = num;
}
string getName()
{
return name;
}
int getId()
{
return id;
}
void getClasses()
{
for (int counter=0; counter <arraySize; counter++) {
cout << classes[counter] << endl;
}
}
};
int main()
{
//Student 1
string s1Name = "John Doe";
int s1Id = 51090210;
int const NUMCLASSES1 = 3;
string s1Classes[NUMCLASSES1] = {"C++","Intro to Theatre","Stagecraft"};
//Student 2
string s2Name = "Rick Harambe Sanchez";
int s2Id = 666123420;
int const NUMCLASSES2 = 2;
string s2Classes[NUMCLASSES2] = {"Intro to Rocket Science","Intermediate Acting"};
//
Student info;
info.setName(s1Name);
info.setId(s1Id);
//info.setClasses(s1Classes, NUMCLASSES1);
cout << "Here is Student #1's information:\n";
cout << "Name: " << info.getName() << endl;
cout << "ID: " << info.getId() << endl;
//cout << "Classes: " << info.getClasses() << endl;
info.setName(s2Name);
info.setId(s2Id);
// info.setClasses(s2Classes, NUMCLASSES1);
cout << "\n\nHere is student #2's information:\n";
cout << "Name: " << info.getName() << endl;
cout << "ID: " << info.getId() << endl;
//cout << "Classes: " << info.getClasses() << endl;
return 0;
}
The usual way to pass around variable-length lists in C++ is to use an std::vector. A vector is a single object that you can easily pass to a function, copying (or referencing) its contents. If you are familiar with Java, it's basically an ArrayList. Here is an example:
#include <vector>
#include <string>
using namespace std;
class foo {
private:
vector<string> myStrings;
public:
void setMyStrings(vector<string> vec) {
myStrings = vec;
}
}
//...
foo myObj;
vector<string> list = {"foo","bar","baz"};
myObj.setMyStrings(list);
If don't want to use the standard library though, you can pass an array C-style. This involves passing a pointer to the first element of the array, and the length of the array. Example:
void processStrings(string* arr, int len) {
for (int i = 0; i < len; i++) {
string str = arr[i];
//...
}
}
string array[] = {"foo","bar","baz"};
processStrings(array, 3); // you could also replace 3 with sizeof(array)
Passing raw arrays like this, especially if you wanted to then copy the array into an object, can be painful. Raw arrays in C & C++ are just pointers to the first element of the list. Unlike in languages like Java and JavaScript, they don't keep track of their length, and you can't just assign one array to another. An std::vector encapsulates the concept of a "list of things" and is generally more intuitive to use for that purpose.
Life lesson: use std::vector.
EDIT: See #nathanesau's answer for an example of using constructors to initialize objects more cleanly. (But don't copy-paste, write it up yourself! You'll learn a lot faster that way.)
You can pass array of any_data_type to function like this
void foo(data_type arr[]);
foo(arr); // If you just want to use the value of array
foo(&arr); // If you want to alter the value of array.
Use std::vector. Also, don't add functions you don't need. Here's an example of using std::vector
#include <string>
#include <iostream>
#include <vector>
using std::string;
using std::vector;
class Student // Student class declaration.
{
private:
vector<string> classes;
string name;
int id;
public:
Student (const vector<string> &classesUse, string nameUse, int idUse) :
classes (classesUse),
name (nameUse),
id (idUse)
{
}
void print ()
{
std::cout << "Name: " << name << std::endl;
std::cout << "Id: " << id << std::endl;
std::cout << "Classes: ";
for (int i = 0; i < classes.size (); i++)
{
if (i < classes.size () - 1)
{
std::cout << classes[i] << ", ";
}
else
{
std::cout << classes[i] << std::endl;
}
}
std::cout << std::endl;
}
};
int main()
{
Student John ({"C++","Intro to Theatre","Stagecraft"},
"John",
51090210);
John.print ();
Student Rick ({"Intro to Rocket Science","Intermediate Acting"},
"Rick",
666123420);
Rick.print ();
return 0;
}
Name: John
Id: 51090210
Classes: C++, Intro to Theatre, Stagecraft
Name: Rick
Id: 666123420
Classes: Intro to Rocket Science, Intermediate Acting
In the private variables of class Student, you are storing a string:
String classes;
where as you should be storing an array of strings like:
String classes[MAX_NUM_CLASSES];
then in the set classes function, pass in an array of strings as the first argument, so it should be :
void setClasses(string[] c, int num)
{
classes = c; //not sure if simply setting them equal will work, rather copy entire array using a for loop
arraySize = num;
}
This should point you in the right direction
Also, use std::vector instead of string[], it will be easier.

C++ Expression must be a modifiable lvalue

writing this program for my c++ class and im running into an issue. My program reads the inputtted name and stores it into name it then wants to check for correct parameters under _name.. here are my class and its header file.
My error is specifically under ::setName where i want to check or set my inputted name with _name for correct output under ::display()
PhoneNumber.cpp
using namespace oop244;
void PhoneNumber::display() const{
cout << "name: " << _name << ", Phone number: (" << _areacode << ") " << _localNumber / 10000 << "-" << _localNumber % 10000 << endl;
}
bool PhoneNumber::isValid() const
{
if (correctNum == false && correctArea == false){
cout << _name << " does not have a valid phone number." << endl;
return false;
}
else{
return true;
}
}
void PhoneNumber::setName(const char name[])
{
cout << name << endl;
_name = name;
}
PhoneNumber.h
#define MAX_NAME_LENGTH 40
#define PHNO_MAX 999999
#define PHNO_MIN 100000
#define AREACODE_MIN 100
#define AREACODE_MAX 999
namespace oop244{
class PhoneNumber{
private:
char _name[MAX_NAME_LENGTH + 1];
int _areacode;
int _localNumber;
bool _validPhoneNumber;
public:
void setName(const char name[]);
void setPhoneNumber(int areaCode, int number);
void display() const;
bool isValid() const;
};
};
use standard string
#include <string>
and use
std::string _name;
in your class declarations instead of
char _name[MAX_NAME_LENGTH + 1];
alternatively use c-style str-functions, as suggested in another answer
You can't assign raw arrays. You need to copy the contents.
Assuming your class teacher forces you to use char arrays, you can for example use strncpy to copy the characters:
strncpy(_name, name, MAX_NAME_LENGTH);
You need to #include <cstring> for this.
If your class teacher allows it, better use std::array<char,MAX_NAME_LENGTH> or even std::string. Both can be copied by assigning.

C++ No instance of overloaded function getline matches argument list

I'm writing a program which needs to read input from cin into a string. When I tried using the regular getline(cin, str) it endlessly prompted for input and never moved on the the next line of code. So I looked in my textbook and it said I could pass a cstring and size of the string to getline in the form of cin.getline(str, SIZE). However, when I do that I get the error "no instance of overloaded function getline matches the argument list.
I searched around, but all I found was people saying to use the getline(cin,str) form which led to the infinite input prompt, or the suggestion that there might be two different getline functions with different parameters in the classes I'm including, and that I need to tell the IDE to use the correct one(I'm not sure how to do that).
This is what I include at the beginning of my file:
#include <string>
#include <array>
#include <iostream>
#include "stdlib.h"
#include "Bank.h" //my own class
using namespace std;
And this is the relevant section of code:
const int SIZE = 30; //holds size of cName array
char* cName[SIZE]; //holds account name as a cstring (I originally used a string object in the getline(cin, strObj) format, so that wasn't the issue)
double balance; //holds account balance
cout << endl << "Enter an account number: ";
cin >> num; //(This prompt works correctly)
cout << endl << "Enter a name for the account: ";
cin.ignore(std::numeric_limits<std::streamsize>::max()); //clears cin's buffer so getline() does not get skipped (This also works correctly)
cin.getline(cName, SIZE); //name can be no more than 30 characters long (The error shows at the period between cin and getline)
I'm using Visual Studio C++ 2012, if that's relevant
This is the offending line:
char* cName[SIZE];
What you really need here is:
char cName[SIZE];
Then, you should be able to use:
cin.getline(cName, SIZE);
This error message from visual studio is quite misleading. Actually for me I was trying to call a non const member function from const member function.
class someClass {
public:
void LogError ( char *ptr ) {
ptr = "Some garbage";
}
void someFunction ( char *ptr ) const {
LogError ( ptr );
}
};
int main ()
{
someClass obj;
return 0;
}
Related to the answer of R Sahu the compiler gives a clue that the argument does not match.
Try the following code which does not give the error and makes the error message more clear.
#include <iostream>
class someClass {
public:
void LogError(char* ptr) {
std::cout << "LogError: before arg=" << ptr << "\n";
ptr[0] = 0;
std::cout << "LogError: after arg=" << ptr << "\n";
}
void LogError(char* ptr) const {
std::cout << "const LogError: arg=" << ptr << "\n";
}
void ROFunction(char* ptr) const {
LogError(ptr);
}
void RWFunction(char* ptr) {
LogError(ptr);
}
};
int main()
{
char s[] = "test";
someClass obj;
obj.ROFunction(s);
obj.RWFunction(s);
obj.ROFunction(s);
return 0;
}
With the output:
const LogError: arg=test
LogError: before arg=test
LogError: after arg=
const LogError: arg=