storing data into a strucutre array from a txt file - c++

#include <iostream>
#include <string.h>
#include <string>
#include<fstream>
struct time
{
int hours, minutes;
};
struct moviedata
{
string moviename, genre, actorname1, actorname2;
int yearreleased, priceperday;
time duration;
};
void readmoviedata(moviedata *ptr) /*not ale to run this code*/
{
int i = 0;
string x;
ifstream inside("movies.txt");
while (!inside.eof())
{
getline(inside, ptr[i].moviename);
inside >> ptr[i].yearreleased;
getline(inside, ptr[i].genre);
inside >> ptr[i].duration.hours;
inside >> ptr[i].duration.minutes;
getline(inside, ptr[i].actorname1);
getline(inside, ptr[i].actorname2);
inside >> ptr[i].yearreleased;
i++;
}
}
int main()
{
moviedata *md = new moviedata;
readmoviedata(md);
delete md;
return 0;
}
can anyone tell me what i did wrong with function readmoviedata
$ when runned line by line as soon as the function readmoviedata is called
$ black grid appears with cursor blinking and nothin else

Problem is that you are creating the one pointer variable of struct type.
moviedata *md = new moviedata;
and you are treating this variable like array.
ptr[i].yearreleased;

Related

c++ Process returned -1073741819 (0xC0000005)

Here is the whole code.
I know that the problem is somewhere in the hozzaad function, but I don't know to debug it.
I want to create a dynamic 2d array, with exacly vagonszam columns, but the number of rows differ.
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdlib>
using namespace std;
class Vonat{
int vagonszam, maxtomb;
int **vagonok;
int *seged;
enum szallitmany {szen, fa, ko} ;
public:
void beolvas(int x);
Vonat(): vagonszam(0), maxtomb(0) {}
void kiir();
void hozzaad(int **vagonok, int i, string szallitmany);
};
void Vonat::hozzaad(int **vagonok, int i, string szallitmany)
{
++vagonok[i][0];
seged = (int *) realloc(vagonok[i], ((vagonok[i][0]+1)*sizeof(int)));
seged[vagonok[i][0]]=1;
}
void Vonat::beolvas(int x)
{
char szovegesallomany[]="beVagonTartalma";
szovegesallomany[15]=x+'0';
szovegesallomany[16]='\0';
strcat(szovegesallomany, ".txt");
ifstream f(szovegesallomany);
f>>vagonszam>>maxtomb;
vagonok = new int*[vagonszam];
string szallitmany;
for(int i=0;i<vagonszam;i++)
{
vagonok[i] = new int[1];
vagonok[i][0]=0;
do
{
f>>szallitmany;
cout<<szallitmany<<" ";
hozzaad(vagonok, i, szallitmany);
}
while(szallitmany!="*");
}
f.close();
}
void Vonat::kiir()
{
cout<<vagonszam<<" "<<maxtomb<<endl;
}
int main()
{
Vonat v_52164;
v_52164.beolvas(1);
v_52164.kiir();
Vonat v_54587;
v_54587.beolvas(2);
v_54587.kiir();
return 0;
}
In this code something's wrong, because after running it gets the error message specified before.
Thanks to everyone, who try to help me, all the best.

Passing a dynamic array of structs c++

I need to read a .txt file and use the first number as the array size in a function called getData.
In my code, I am able to read the file and assign it to the array size as listSize. I am also able to fill the rest of the array with the .txt information. When I print out what is in my array WITHIN the getData function, it works.
The problem is that when I try to access the array outside of the getData function my program crashes. I am new to pointers, and c++ in general. I don't think I am passing it or calling it correctly. I have had a hard time finding information to assist me in the problem.
How can I access the arrays I created in getData?
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
struct menuItemType
{
string menuItem;
double menuPrice;
};
void getData(int& listSize, menuItemType menuList[], int orderList[]);
int main()
{
menuItemType *menuList = 0; //-----pointers
int *orderList = 0;
int listSize;
getData(listSize, menuList, orderList);
cout << menuList[0].menuItem; //-----This is what crashes the program
return 0;
}
//-----Get Menu Function
void getData(int& listSize, menuItemType menuList[], int orderList[])
{
//-----Declare inFile
ifstream inFile;
string price, size;
//-----Open inFile
inFile.open("Ch9_Ex5Data.txt");
//-----Get Amount of Items, Convert to int
getline(inFile, size);
listSize = stoi(size);
//-----Set Array Size
menuList = new menuItemType[listSize];
orderList = new int[listSize];
//-----Get Menu
for (int x = 0; x < listSize; x++)
{
//-----Get menuItem
getline(inFile, menuList[x].menuItem);
//-----Get menuPrice convert to double
getline(inFile, price);
menuList[x].menuPrice = stod(price);
}
//------PRINT WORKS HERE ----- This print made me think i created the
//arrays correctly
for (int x = 0; x < listSize; x++)
{
cout << menuList[x].menuItem << endl
<< menuList[x].menuPrice
<< endl;
}
inFile.close();
}
The contents of the .txt
8
Plain Egg
1.45
Bacon and Egg
2.45
Muffin
0.99
French Toast
1.99
Fruit Basket
2.49
Cereal
0.69
Coffee
0.50
Tea
0.75
Setting menuList and orderList in getData does not update the pointers in main. It would if you used references to pointers:
void getData(int& listSize, menuItemType*& menuList, int*& orderList);
Even better, use references to std::vector and quit mucking around with owning pointers and new and delete.
Let's Rewrite your code for a better C++ness, with explanations. :)
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
Don't do using namespace std just because you can type less things, namespaces helps you by telling you where this particular thing you invoked came from. if you really wanna write string instead of std::string, pull that particular thing, not the whole namespace, like this:
using std::string;
Your struct seems right, but you need to choose if your types will start with capitals or not, I always start my types with capitals but this is a choice:
struct MenuItemType
{
string menuItem;
double menuPrice;
};
Now, your getData should, well, get your data. so the type matters. your data is not 'void' as you declared, it's an array of MenuItemType, you can then declare them as vector and not even care about pointers.
Other thing: all of your parameters in getData shouldn't be parameters - they are all things that you would get from the text file that your program will parse, so the only thing that matters for the getData is the text file, so this is your variable.
std::vector<MenuItemType> getData(const std::string& textFile)
{
std::ifstream inFile;
std::string price, size, item;
inFile.open(textFile);
getline(inFile, size);
int listSize = stoi(size);
std::vector<MenuItemType> result;
result.reserve(listSize);
for (int x = 0; x < listSize; x++)
{
getline(inFile, item);
getline(inFile, price);
result.push_back(MenuItemType{item, stod(price)});
}
return result;
}
See how I didn't closed the file? It will be closed as soon as you leave the function, there's no need to call that unless you need the file to close before the function finishes.
Thumbs up rule: don't deal with pointers unless you have to.
As for your main function:
int main()
{
std::vector<MenuItemType> menuList = getData("Ch9_Ex5Data.txt");
cout << menuList[0].menuItem;
return 0;
}
You could rewrite that in a faster way if you are sure what types are you using, the code above is equivalent to this one:
int main()
{
auto menuList = getData("Ch9_Ex5Data.txt");
cout << menuList[0].menuItem;
return 0;
}

C++ Object doesn't save value

Objects I created for the Player class does not change the private variable even tho it does in the function that changes it. There maybe some reference problems with the objects being used in the main() function but I can't figure out where or why.
Specifically the loop at the end of the main file prints the games won by the players in the vector Players but all the scores return 0. While when the player object.matchWon() function correctly parse and print the score and shows the change made to the private variable.
I suspect there are problems with the usage of getPlayer() function in the main code.
Thanks in advance!!
Player.cpp:
#include "Player.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
//constructor
Player::Player(string first, string last) {
Player::first = first;
Player::last = last;
gWins = 0;
gLoss = 0;
mWins = 10;
mLoss = 2;
}
//setters
void Player::addLoss(int increment) {
this->gLoss+=increment;
}
void Player::addWins(int increment) {
this->gWins+=increment;
}
void Player::matchWon(vector<string> scores) {
for (int i = 5;i<scores.size()-1;i++){
cout<<(int)scores[i][0]-'0'<<"-";
cout<<(int)scores[i][2]-'0'<<endl;
gWins+=scores[i][0]-'0'; //add games won
cout<<gWins<<endl;
gLoss+=(int)scores[i][2]-'0'; //add games lost
}
this->mWins++;
}
void Player::matchLost(vector<string> scores) {
this->mLoss++;
}
double Player::winPercentage() {
return (double)mWins / mLoss;
}
//accessors
string Player::getFirstname() {
return this->first;
}
string Player::getLastname() {
return this->last;
}
int Player::getGameswon() {
//cout<<gWins;
return this->gWins;
}
main.cpp:
#include <iostream>
#include "player.h"
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
vector<string> split(const string &s) {
vector<string> elems;
istringstream iss(s);
do
{
string sub;
iss >> sub;
elems.push_back(sub);
//cout << "Substring: " << sub << endl;
} while (iss);
return elems;
}
Player &getPlayer(vector<Player> &players, const string &first, const string &last){
for (int i=0;i<players.size();i++){
if (players[i].getFirstname()==first&&players[i].getLastname()==last){
return players[i];
}
}
players.push_back(Player(first,last));
return (players[players.size()-1]);
}
int main(int argc, char *argv[]) {
ifstream file(argv[1]);
ofstream ofile(argv[2]);
if (!file.is_open()){
cerr <<"Could not open file\n";
return 0;
}
string line;
vector<Player> players;
while (getline(file,line).good()){
vector<string> lineParsed = split(line);
vector<string> matchData = split(line);
Player p1 = getPlayer(players,lineParsed[0],lineParsed[1]);
Player p2 = getPlayer(players,lineParsed[3],lineParsed[4]);
p1.matchWon(lineParsed);
cout<<p1.getFirstname()<<"!"<<p1.getGameswon()<<endl;
}
for (int i=0;i<players.size();i++){
//cout<<players.size();
cout<<players[i].getFirstname()<<":"<<players[i].getGameswon()<<endl;
}
return 0;
}
You're copying your players:
Player p1 = getPlayer(players,lineParsed[0],lineParsed[1]);
Player p2 = getPlayer(players,lineParsed[3],lineParsed[4]);
so when you p1.matchWon(), it happens to the local Player object, not the one in the vector.
Although the return type of getplayer() is Player&, that doesn't matter if you're assigning it to a non-reference variable. If you want to be modifying the Player instances in the vector, you should have
Player& p1 = getPlayer(players,lineParsed[0],lineParsed[1]);
Player& p2 = getPlayer(players,lineParsed[3],lineParsed[4]);
By the way, getPlayer() is unsafe. The vector might resize itself when you push_back to it, invalidating references. You may want to store a vector of pointers instead (or just make sure through e.g. resize() that the vector definitely has room for all the players you want to push to it).
It would help if you included the class definition. There seems to be something strange going on:
Player::first = first;
Player::last = last;
Are these static fields? If they are, the issue is that you only store the first and last (names?) of the last player you create.

c++ segmentation fault for dynamic arrays

I want to add a theater object into a boxoffice object in a C++ code. When I try to add it in main code, first one is added successfully. But a segmentation fault occurs for second and obvioulsy other theater objects. Here is the add function;
#include <iostream>
#include <string>
#include "BoxOffice.h"
using namespace std;
BoxOffice::BoxOffice()
{
sizeReserv = 0;
sizeTheater = 0;
theaters = new Theater[sizeTheater];
reserv = new Reservation[sizeReserv];
}
BoxOffice::~BoxOffice(){}
void BoxOffice::addTheater(int theaterId, string movieName, int numRows, int numSeatsPerRow){
bool theaterExist = false;
for(int i=0; i<sizeTheater; i++)
{
if(theaters[i].id == theaterId)
{
theaterExist=true;
}
}
if(theaterExist)
cout<<"Theater "<<theaterId<<"("<<movieName<<") already exists"<< endl;
else
{
++sizeTheater;
Theater *tempTheater = new Theater[sizeTheater];
if((sizeTheater > 1)){
tempTheater = theaters;
}
tempTheater[sizeTheater-1] = Theater(theaterId,movieName,numRows,numSeatsPerRow);
delete[] theaters;
theaters = tempTheater;
cout<<"Theater "<<theaterId<<"("<<movieName<<") has been added"<< endl;
cout<<endl;
delete[] tempTheater;
}
}
And I get segmentation fault on this line;
tempTheater[sizeTheater-1] = Theater(theaterId,movieName,numRows,numSeatsPerRow);
This is Theater cpp;
#include "Theater.h"
using namespace std;
Theater::Theater(){
id=0;
movieName="";
numRows=0;
numSeatsPerRow=0;
}
Theater::Theater(int TheaterId, string TheaterMovieName, int TheaterNumOfRows, int TheaterNumSeatsPerRow)
{
id = TheaterId;
movieName = TheaterMovieName;
numRows = TheaterNumOfRows;
numSeatsPerRow = TheaterNumSeatsPerRow;
theaterArray = new int*[TheaterNumOfRows];
for(int i=0;i<TheaterNumOfRows;i++)
theaterArray[i]= new int[TheaterNumSeatsPerRow];
for(int i=0; i<TheaterNumOfRows;i++){
for(int j=0;j<TheaterNumSeatsPerRow;j++){
theaterArray[i][j]=0;
}
}
}
This is header file of Theater;
#include <iostream>
#include <string>
using namespace std;
class Theater{
public:
int id;
string movieName;
int numRows;
int numSeatsPerRow;
int **theaterArray;
Theater();
Theater(int TheaterId, string TheaterMovieName, int TheaterNumOfRows, int TheaterNumSeatsPerRow);
};
And this is how i call add functions;
BoxOffice R;
R.addTheater(10425, "Ted", 4, 3);
R.addTheater(8234, "Cloud Atlas", 8, 3);
R.addTheater(9176, "Hope Springs",6,2);
The problematic lines are these:
if((sizeTheater > 1)){
tempTheater = theaters;
}
First you allocate memory and assign it to tempTheater, but here you overwrite that pointer so it will point to the old memory. It does not copy the memory. Since the code is for a homework assignment, I'll leave it up to you how to copy the data, but I do hope you follow the rule of three for the Theater class (as for the BoxOffice class) which will make it very simple.
Also, there's no need to allocate a zero-size "array", just make the pointers be nullptr (or 0).

dynamically allocate memory to struct array c++

let me start by saying I know this is a funky way to program, but my teacher is requiring us to go about it this way.
also:
I CANT use std::string, classes, constructors for this project.
I am required to use this archaic method of c-style strings with dynamic memory allocation occuring outside the struct.. i know its not the best way to go about this, but theres nothign i can go. :(
Im stuck with the structs, I cant figure out whats wrong..
I have a struct
#include <iostream>
#include <fstream>
#include <ctime>
#include <stdlib.h>
#include <string>
using namespace std;
//global constant(s)
const int maxCards = 52;
//Structs
struct card
{
char *suit;
char *rank;
int cvalue;
char location;
};
//Function List
void readPlayers(player *peoplePointer);
void shuffleCards(card *unshuffled, card* shuffled);
//program
int main()
{
//create pointer and set initial value
card * deckPointer = new card[52];
card *deckHome = &deckPointer[0];
for(int i=0;i<maxCards;i++)
{
(*deckPointer).suit=new char[8];
(*deckPointer).rank = new char[7];
deckPointer++;
}
deckPointer = deckHome;
cardInit(deckPointer);
readDeck(deckPointer);
//sets default values for the card arrays
for(int i=0;i<52;i++)
{
strcopy((*deckPointer).suit,"suit");
strcopy((*deckPointer).rank,"rank");
(*deckPointer).cvalue = 0;
deckPointer++;
}
deckPointer = deckHome;
return 0;
}
//Functions
void cardInit(card *deckPointer)
{
card * deckHome = NULL;
deckHome = &deckPointer[0];
//set up card file to be read in
ifstream fin;
char *finName = new char[13];
//get file name from user
cout << "Enter file name...(cardFile.txt)" << endl;;
cin >> *finName;
//open the file
fin.open(finName);
//check if cardFile.txt opens correctly
if(!fin.good())
{
cout << "Error with card file" << endl;
}
else
{
deckPointer = deckHome;
while(fin.good())
{
for(int i=0;i<50;i++)
{
fin >> (*deckPointer).suit;
fin >> (*deckPointer).rank;
fin >> (*deckPointer).cvalue;
deckPointer++;
}
}
}
delete [] finName;
}
//Its a pretty simple program..and my dynamic memory works for
//the file name, but I cant figure out why it doesnt work for structs?
For your code to work, you will need a typename card.
to this end you will need to setup the following:
struct cardstruct {
char *suit;
char *rank;
int cvalue;
};
typedef struct cardstruct card;
otherwise, when you declare the pointers, you would need to use the "struct" keword first. E.G.:
struct card *deckPtr = new struct card[52];