Reputation: 21
i am trying to input a string in my code in c++ and when i run i always get the following error: Exception thrown at 0x0F5023F5 (msvcp140d.dll) in assignment-1.exe: 0xC0000005: Access violation writing location 0x00229C20. i will post my code below if anyone could help me that would be great.Please note that i already know that its a problem with me trying to access the memory location on which you dont have access to, i just dont know how to fix it.
HEADER FILE:
#ifndef item_H
#define item_h
class item
{
private:
//attributes
int itemID;
char itemName[20];
float itemcost;
float itemprice;
//utility function
float calcPrice();
public:
//constructor
item(int = 000, char[] = "itemUnknown", float = 0,float = 0);
//destructor
~item();
//set functions
void setAll(int, char[], float, float);
void setID(int);
void setName(char[]);
void setCost(float);
//get function
int getID();
float getcost();
float getprice();
void getname();
//print function
void print();
};
#endif
CPP:
#include "Dariush.h"
#include <iostream>
#include <iomanip>
#include<string>
using namespace std;
//constructor will set attributes
item::item(int ID, char n[] , float c,float p)
{
setID(ID);
setName(n);
setCost(c);
setAll(ID, n, c, p);
}
//destructor will print destroing two objects
item::~item()
{
cout << "destroing two objects : " << " " << itemName << " "
<< " & " << itemName << endl;
}
//set functions :
void item::setID(int ID)
{
cout << "please enter the item's ID : " << endl;
cin >> ID;
}
void item::setName(char n[])
{
cout << "please enter the item's name" << endl;
cin.ignore();
cin.getline(n, 20);
}
void item::setCost(float c)
{
cout << "please enter the item's cost : " << endl;
cin >> c;
}
void item::setAll(int ID, char n[], float c, float p)
{
itemID = (ID > 0 && ID < 999) ? ID : 0;
strcpy_s(itemName, n);
itemcost = (c > 0) ? c : 0;
calcPrice();
}
//get functions :
int item::getID()
{
return itemID;
}
float item::getcost()
{
return itemcost;
}
float item::getprice()
{
return itemprice;
}
void item::getname()
{
cout << itemName << endl;
}
//print function :
void item::print()
{
cout << "ID : " << itemID << endl
<< "Name : " << itemName << endl
<< "cost : " << itemcost << endl
<< "price : " << itemprice << endl;
}
// utility function for price callculation :
float item::calcPrice()
{
if (itemcost < 1000)
{
itemprice = itemcost + (itemcost*0.1);
}
else
itemprice = itemcost + (itemcost*0.2);
return itemprice;
}
MAIN.CPP:
#include "Dariush.h"
#include <iostream>
#include<string>
using namespace std ;
void main()
{
item i1;
item i2;
i1.print();
i2.print();
}
thanks for the assistance.
Upvotes: 1
Views: 290
Reputation: 7788
There are many problems with this code, but the one that is causing the access violation is:
void item::setName(char n[])
{
cout << "please enter the item's name" << endl;
cin.ignore();
cin.getline(n, 20); //here
}
You should use cin.getline(itemName, 20);
instead.
Also, to prevent such error in the future, declare arguments as char const n[]
instead of char n[]
- good compiler should display a warning when you use string literals with non-const pointer as argument.
Upvotes: 0
Reputation: 409186
Lets take a closer look at these three function declarations:
item(int = 000, char[] = "itemUnknown", float = 0,float = 0);
void setAll(int, char[], float, float);
void setName(char[]);
The thing here is that the character "array" arguments you declare are not really arrays at all. Instead they are pointers. When declaring arguments, e.g. char n[]
is actually translated by the compiler as char *n
.
The constructor declaration makes the pointer point to the constant string literal ""
. And the important thing about constant string literals is that they are indeed constant. Trying to modify a string literal leads to undefined behavior. And change this literal is what you are trying to do with the cin.getline(n, 20)
call in the setName
function. Not only that, but you are also telling the cin.getline
function to read more than fits in the string literal.
The simple solution is to have setName
read into the member variable itemName
instead.
Upvotes: 1