C++ Primer Exercise 2.41 [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm stucked at 1 exercise which was at the end of the chapter 2 ! My problem with this exercise is that I can't figure out how to make logically loop to ask several times the input ! I wrote the code which ask twice for the input ! Previously with book provided header I did that task easy but that way didn't work anymore . So I'll give you the exercise and code and hope you can help me. And sorry for my English.
Exercise
Write program which will have a class in same place where you main function.
Write Code which will read several transaction with same Book Number and count each transaction with that book number.
My Code
#include <iostream>
#include <string>
using namespace std;
//Data structure Code
struct Sales_Data
{
std::string bookNo;
unsigned unit_sold;
double revenue;
};
int main()
{
Sales_Data data1,data2; //Data wich will hold input
double price; //Price per book used to calculate total revenue
// Checking if there was data input of book number units sold and price
if (std::cin>>data1.bookNo>>data1.unit_sold>>price)
{
int cnt=1; //Start Counter
data1.revenue=data1.unit_sold*price;// data1 calculating total revenue from price and unit_sold
while (std::cin>>data2.bookNo>>data2.unit_sold>>price)
{
data2.revenue=data2.revenue*price;
//checking if book name is same
if (data1.bookNo == data2.bookNo)
{
++cnt; //Incrementing counter if they same
unsigned totalCnt=data1.unit_sold+data2.unit_sold;
double totalRevenue=data1.revenue+data2.revenue;
//Print out result
std::cout<<cnt<<data1.bookNo<<" "<<totalCnt<<" "<<totalRevenue<<" ";
getchar();
getchar();
getchar();
if (totalCnt != 0)
std::cout<<totalCnt/totalRevenue;
else
std::cout<<"(No Sales)"<<std::endl;
return 0;
}else{
std::cerr<<"Book numbers isn't same"<<std::endl;
return -1;
}
}
}
return 0;
}
And also wast sure why but the revenue gives me garbage number.
Thank you for your time.

Did you init the data2.revenue before using it?
data2.revenue=data2.revenue*price;
To init data2, you could:
struct Sales_Data
{
std::string bookNo;
unsigned unit_sold;
double revenue;
Sales_Data(std::string s = "", unsigned u = 0, double r = 0)
: bookNo(s), unit_sold(u), revenue(r) {}
};
or
Sales_Data data2 = { "a", 0, 0 };
or
Sales_Data data2;
data2.bookNo = "";
data2.unit_sold = 0;
data2.revenue = 0;
For multiple inputs:
#include <map>
#include <string>
#include <iostream>
using namespace std
int main()
{
map<string, Sales_Data> count;
Sales_Data data;
while (cin >> data.bookNo >> data.unit_sold) { // <- this will allow you read multiple transactions
if (map.find(data.bookNo) != count.end()) {
count[data.bookNo].unit_sold += data.unit_sold;
// and do some other thing.
} else {
count[data.bookNo] = data.
}
}
return 0;
}

Related

First time writing header file and .cpp from existing main; no output [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
It's my first time creating a header and cpp file for an existing main. I can get the program to run, but there's no output. If anyone can help me troubleshoot, i would much appreciate it. The program is supposed to simulate an elevator. thanks!
Here is what i was given:
int main()
{
elevator aLift(1);
aLift.select(5);
aLift.select(3);
system("pause");
return 0;
}
Here is my header file.
#ifndef elevator_h
#define elevator_h
#include <string>
using namespace std;
class elevator {
public: //operations
elevator();
//coonstructors
elevator (int initFloor);
//modifiers
void select (int newFloor);
//my floor is increased/decreased by difference.
//accessors
int getFloor() const;
//gets current floor number
private: //state
int my_floor;
int selected_floor;
};
#endif // ifndef elevator_h
Lastly, here's my cpp file
#include "elevator.h"
#include <string>
#include <iostream>
using namespace std;
int selected_floor;
elevator;
elevator::elevator (int initFloor)
//coonstructors
{
my_floor=initFloor;
}
//modifiers
void elevator::select (int)
{
while(my_floor < selected_floor)
cout << "Going up to " << ++my_floor << endl;
}
//my floor is increased/decreased by difference.
//accessors
int elevator::getFloor() const
{
return selected_floor;
}
Global variables are initialized 0, see here.
So your selected_floor is 0 and smaller as my_floor.
Edit:
At first glance I missed you have a member selected_floor and a global one. I think you don't need the global one.
What you are missing is:
// don't forget the default constructor
elevator::elevator ()
: my_floor(0)
, selected_floor(0)
{}
elevator::elevator (int initFloor)
: my_floor(initFloor)
, selected_floor(0)
{}
//modifiers
void elevator::select (int newFloor)
//^^^^^^^^
{
selected_floor = newFloor; // set you selected_floor to the value you want to select
//^^^^^^^^^^^^^^^^^^^^^^^^^^
while(my_floor < selected_floor)
cout << "Going up to " << ++my_floor << endl;
}
There are couple of things not clear.
From the cpp.
int selected_floor; // You have a global variable with the same name as a private variable. Anything specific you intend to do?
elevator; //This should not even compile.
What is this ?
//modifiers
void elevator::select (int)
Maybe you wanted something like this.
void elevator::select (int floor) {
selected_floor = floor;
Get rid of the global variable and make the change to ::select, it should be ok.
It will not execute because you have not initiated selected_floor and you are using it , it has a value of 0 . So when you are running the loop the "my_floor" which has a initial value of 1 is being tested against zero which is already greater than zero , that is there is no output on the screen .
What you should do is , first assign a value to selected_floor and then call the select function . you can assign the value to selected_floor in the select function itself before executing the loop .
void elevator::select (int newFloor)
{
selected_floor = newFloor ;
while(my_floor < selected_floor)
cout << "Going up to " << ++my_floor << endl;
}

Calling a function gives result only if it has a cout statement in the beginning [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm trying to implement a simple stack in C++. My code is working fine except this function minm(). I'm getting very unexpected result. If I comment out the line in bold then my procedure doesn't even run. Also, you can see that the only difference between my functions minm() & minmm() is of the bold line. Please help me out.
The explanation is as follows:
Functions minm() & minmm() under consideration are in italic & this line cout<<"called"<< endl; is in bold
#include<iostream>
using namespace std;
const int MAX_ALLOWED_SIZE = 100000000;
class MyStack{
int *a;
int *min, *max;
int top;
int size;
public:
MyStack(int s=MAX_ALLOWED_SIZE);
void push(int i);
int pop();
int maxm();
int minm() // This function is failing
{
//cout<<"called\t";
if(!stackEmpty())
{
cout<<min[top]<<" = " <<a[min[top]]<<endl;
return a[min[top]];
}
return NULL;
}
int minmm() // This function is working
{
cout<<"called\t";
if(!stackEmpty())
{
cout<<min[top]<<" = " <<a[min[top]]<<endl;
return a[min[top]];
}
return NULL;
}
bool stackEmpty();
void printStack();
};
int main()
{
MyStack s;
int t;
while(true)
{
scanf("%d",&t);
s.push(t);
cout<<"min = "<<s.minm()<<endl;
cout<<"min = "<<s.minmm()<<endl;
if(t==-1) break;
}
}
Input:
234
23
-1
Output:
min = 0
called a[0] = 234
min = 234
min = 0
called a[1] = 23
min = 23
min = 0
called a[2] = -1
min = -1
Now, I'm getting same (wrong) result from both functions on ideone while function minmm() returns on my system (I use GNU GCC compiler in Code::Blocks 12.11).
In your stackEmpty, your are not returning false:
bool stackEmpty(){
if(top == -1) return true;
return false;
}
or
bool stackEmpty(){
return (top == -1);
}

wrong answer from boolean function [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
My boolean function check_gift is not working properly.
I copied a txt file into the vector giftstore. Now I want to check if a given item is in the store. To test the function check_gift I took an item from the actual txt file but the function gives the wrong answer. It returns false instead of true.
What am I doing wrong?
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstdlib>
#include <string>
#include <cassert>
using namespace std;
typedef vector<string> Wishes;
int size(Wishes& w){ return static_cast<int>(w.size()); }
struct Wishlist
{
double budget;
Wishes wishes;
};
struct Gift
{
double price;
string name;
};
typedef vector<Gift> Giftstore;
int size(Giftstore& g) { return static_cast<int>(g.size()); }
void read_wishlist_into_struct(ifstream& infile, Wishlist& wishlist)
{
double b;
infile>>b;
wishlist.budget=b;
int i=0;
string name;
getline(infile,name);
while(infile)
{
wishlist.wishes.push_back(name);
i++;
getline(infile,name);
}
infile.close();
}
void show_wishlist(Wishlist wishlist)
{
cout<<"Budget: "<<wishlist.budget<<endl<<endl;
cout<<"Wishes: "<<endl;
for(int i=0; i<size(wishlist.wishes); i++)
{
cout<<wishlist.wishes[i]<<endl;
}
cout<<endl;
}
void read_giftstore_into_vector(ifstream& infile, Gift& gift, Giftstore& giftstore)
{
double p;
string name;
int i=0;
infile>>p;
while(infile)
{
gift.price=p;
getline(infile,name);
gift.name=name;
giftstore.push_back(gift);
i++;
infile>>p;
}
infile.close();
}
void show_giftstore(Giftstore giftstore)
{
cout<<"All possible gifts in giftstore: "<<endl<<endl;
for(int i=0; i<giftstore.size(); i++)
{
cout<<giftstore[i].price<<"\t"<<giftstore[i].name<<endl;
}
cout<<endl;
}
bool check_gift(Giftstore giftstore, string giftname)
{
int i=0;
while(i<size(giftstore))
{
if(giftstore[i].name==giftname)
{
cout<<"Yes"<<endl;
return true;
}
else
{
i++;
}
}
return false;
}
void clear(Wishlist& b)
{
b.budget=0;
while(!b.wishes.empty())
{
b.wishes.pop_back();
}
}
void copy(Wishlist a, Wishlist& b)
{
b.budget=a.budget;
for (int i=0; i<size(b.wishes); i++)
{
b.wishes.push_back(a.wishes[i]);
}
}
int main ()
{
ifstream infile2("giftstore.txt");
Gift gift;
Giftstore giftstore;
read_giftstore_into_vector(infile2, gift, giftstore);
show_giftstore(giftstore);
string giftname;
giftname="dvd Up van Pixar";
bool x;
x=check_gift(giftstore, giftname);
cout<<"in store?: "<<x<<endl;
return 0;
}
Learn how to debug. If you cannot trace line-by-line through your code, then try to keep some kind of log.
For now at least output this to the console.
In your case
1. Verify the input file opened successfully
2. Print out each gift as you read it in.
would be a good way to start.
If you want to be able to put multiple log statements in and then remove them later, you can use a macro which can be turned off in one place.
Logging is a fairly tricky skill to be effective for large projects which continue to run into production, however you should learn how to do it in the short-term to debug your program.
We here cannot even see what is in your input file. This is why people are downvoting your question.
Ok: Now you've told me your issue is you need to trim whitespace from the front of each string you read in.
There are multiple ways to do that but
trimmed = s.substr( s.find_first_not_of(" \n\r\t" ) );
will probably work for now.
However my original answer still holds: please learn to debug. If you'd outputted the strings as you read them in, you would have seen these leading spaces.

C++ run error: pointer being freed was not allocated [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm learning c++ and am working on a program that keeps giving me a 'pointer being freed was not allocated' error. It's a grocery store program that inputs data from a txt file, then user can enter item# & qty. I've read through similar questions but what's throwing me off is the 'pointer' issue. I would appreciate if someone could take a look and help me out. I'm using Netbeans IDE 7.2 on a Mac.
I'll just post the whole piece I have so far. Thx.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Product
{
public:
// PLU Code
int getiPluCode()
{
return iPluCode;
}
void setiPluCode( int iTempPluCode)
{
iPluCode = iTempPluCode;
}
// Description
string getsDescription()
{
return sDescription;
}
void setsDescription( string sTempDescription)
{
sDescription = sTempDescription;
}
// Price
double getdPrice()
{
return dPrice;
}
void setdPrice( double dTempPrice)
{
dPrice = dTempPrice;
}
// Type..weight or unit
int getiType()
{
return iType;
}
void setiType( int iTempType)
{
iType = iTempType;
}
// Inventory quantity
double getdInventory()
{
return dInventory;
}
void setdInventory( double dTempInventory)
{
dInventory = dTempInventory;
}
private:
int iPluCode;
string sDescription;
double dPrice;
int iType;
double dInventory;
};
int main ()
{
Product paInventory[21]; // Create inventory array
Product paPurchase[21]; // Create customer purchase array
// Constructor to open inventory input file
ifstream InputInventory ("inventory.txt", ios::in);
//If ifstream could not open the file
if (!InputInventory)
{
cerr << "File could not be opened" << endl;
exit (1);
}//end if
int x = 0;
while (!InputInventory.eof () )
{
int iTempPluCode;
string sTempDescription;
double dTempPrice;
int iTempType;
double dTempInventory;
InputInventory >> iTempPluCode >> sTempDescription >> dTempPrice >> iTempType >> dTempInventory;
paInventory[x].setiPluCode(iTempPluCode);
paInventory[x].setsDescription(sTempDescription);
paInventory[x].setdPrice(dTempPrice);
paInventory[x].setiType(iTempType);
paInventory[x].setdInventory(dTempInventory);
x++;
}
bool bQuit = false;
//CREATE MY TOTAL VARIABLE HERE!
int iUserItemCount = 0;
do
{
int iUserPLUCode;
double dUserAmount;
double dAmountAvailable;
int iProductIndex = -1;
//CREATE MY SUBTOTAL VARIABLE HERE!
while(iProductIndex == -1)
{
cout<<"Please enter the PLU Code of the product."<< endl;
cin>>iUserPLUCode;
for(int i = 0; i < 21; i++)
{
if(iUserPLUCode == paInventory[i].getiPluCode())
{
dAmountAvailable = paInventory[i].getdInventory();
iProductIndex = i;
}
}
//PLU code entry validation
if(iProductIndex == -1)
{
cout << "You have entered an invalid PLU Code.";
}
}
cout<<"Enter the quantity to buy.\n"<< "There are "<< dAmountAvailable << "available.\n";
cin>> dUserAmount;
while(dUserAmount > dAmountAvailable)
{
cout<<"That's too many, please try again";
cin>>dUserAmount;
}
paPurchase[iUserItemCount].setiPluCode(iUserPLUCode);// Array of objects function calls
paPurchase[iUserItemCount].setdInventory(dUserAmount);
paPurchase[iUserItemCount].setdPrice(paInventory[iProductIndex].getdPrice());
paInventory[iProductIndex].setdInventory( paInventory[iProductIndex].getdInventory() - dUserAmount );
iUserItemCount++;
cout <<"Are you done purchasing items? Enter 1 for yes and 0 for no.\n";
cin >> bQuit;
//NOTE: Put Amount * quantity for subtotal
//NOTE: Put code to update subtotal (total += subtotal)
// NOTE: Need to create the output txt file!
}while(!bQuit);
return 0;
}
iUserItemCount is never initialised. You're invoking undefined behaviour when you use it as an index.
Because you work with statically allocated arrays you probably stumbled upon writing after the end of the array.
You state that the file has exactly 21 entries but what happens with the eof condition? If you read the last entry, the stream still doesn't have the eof bit set. This only happens when you try to read and there is nothing.
After the 21st entry, the loop still continues because the eof bit is not set. It reads garbage information and tries to store it into paInventory[21], but the array was only 21 in size.
//after last read x=21 and eof not set
while (!InputInventory.eof () )
{
//first read causes eof to be set
InputInventory >> iTempPluCode >> sTempDescription >> dTempPrice >> iTempType >> dTempInventory;
//Accessing paInventory[21] here which causes your error
paInventory[x].setiPluCode(iTempPluCode);
//...//
}

Debug Assertion Failed! Expression: _BLOCK_TYPE_IS_VALID [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am getting this error message:
Debug Assertion Failed!
Expression:_BLOCK_TYPE_US_VALID(pHead->nBlockUse)
while trying to do the following
#include <vector>
#include <algorithm>
using namespace std;
class NN
{
public:
NN(const int numLayers,const int *lSz,const int AFT,const int OAF,const double initWtMag,const int UEW,const double *extInitWt);
double sse;
bool operator < (const NN &net) const {return sse < net.sse;}
};
class Pop
{
int popSize;
double a;
public:
Pop(const int numLayers,const int *lSz,const int AFT,const int OAF,const double initWtMag,const int numNets,const double alpha);
~Pop();
vector<NN> nets;
void GA(...);
};
Pop::Pop(const int numLayers,const int *lSz,const int AFT,const int OAF,
const double initWtMag,const int numNets,const double alpha)
{
popSize=numNets;
a=alpha;
nets.reserve(popSize);
for(int i=0;i<popSize;i++)
{
NN *net = new NN (numLayers,lSz,AFT,OAF,initWtMag,0,0);
nets.push_back(*net);
}
}
void Pop::GA()
{
...
sort(nets.begin(),nets.end());
...
}
The error appears to be related to the sort function. I check all instances of nets vector and they seem to be OK, having different sse's. The funny thing is that I created a simpler case of the above code (see below) and it worked without any errors. I am wrecking my brain. Please help.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Student
{
public:
string name;
double grade;
Student(string,double);
bool operator < (const Student &st) const {return grade < st.grade;}
};
Student::Student(string stName,double stGrade)
{
name = stName;
grade = stGrade;
}
int main()
{
vector<Student> group;
Student *st;
st = new Student("Bill",3.5);
group.push_back(*st);
st = new Student("John",3.9);
group.push_back(*st);
st = new Student("Dave",3.1);
group.push_back(*st);
sort(group.begin(),group.end());
for each(Student st in group)
cout << st.name << " " << st.grade << endl;
cin.get();
return(0);
}
The _BLOCK_TYPE_IS_VALID assertion gets fired, when you overwrite the header of an block allocated by new. This happens when you slice objects, use dead objects, etc.
You should have a look at your complete code, and try to work from the data you have in your debugger. This short code snippet contains several 'curious' usage of C++, but no obvious point at which this produces the described error (at least for me).
from my experience- This type of error could be caused by Heap corruption. so.. you must first check for memory leaks. If you are using Visual studio use _CrtCheckMemory().
Thanks everybody. First, I clear the memory allocated for nets vector inside the Pop destructor by
Pop::~Pop()
{
//nets.clear();
nets.~vector<NN>();
}
The error message does not say much and I would appreciate if somebody shows me how to make MSVC 2008 to show a more detailed info. Here is what it says (I can't cut and paste it for some reason, so I am retyping it):
Debug assertion failed!
Programm: ... GANN.exe
File: ... dbgedl.cpp
line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information how ...
When I press debug, the compiler shows me line 52 of file dbgdel.cpp:
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
inside
void operator delete(void *pUserData)
Here is a more of my code showing what happens before I try to sort
double Pop::GA(...)
{
for (int gen=0;gen<ngen;gen++)
{
int istart=0;
if(gen>0) istart=eliteSize;
for(int i=istart;i<popSize;i++)
nets[i].getSSE(in,tgt,ntr,discount);
for(int i=istart;i<popSize;i++)
{
cout << i << " " << nets[i].sse << endl;
}
sort(nets.begin(),nets.end());
Everything works properly up to the sort() point. The lSz pointer is used inside NN to hold the number of nodes in each layer of the neural network, for example lSz[3]={12,5,1} (12 inputs, one hidden layer with 5 neurons and one output). It is used to create a 3D array of the weights for each connection of the network. Each network NN (there are 100 of them) inside the Population has its own weight array. But they share the same lSz[] and other structural parameters, which unfortunately get copied from other NN instance to the other. I wanted to use static to declare these shared class members, but that would prevent parallelization.
I just discovered that if I do Pop construction like this
Pop::Pop(const int numLayers,const int *lSz,const int AFT,const int OAF,
const double initWtMag,const int numNets,const double alpha)
{
popSize=numNets;
a=alpha;
cout << "defined a\n";
nets.reserve(popSize);
NN *net = new NN (numLayers,lSz,AFT,OAF,initWtMag,0,0);
for(int i=0;i<popSize;i++)
{
//NN *net = new NN (numLayers,lSz,AFT,OAF,initWtMag,0,0);
nets.push_back(*net);
}
}
Then everything works, including sort(). But, that does not work for me because now the nets vector contains the same instance of NN popSize times. The idea was to intialize each of these instances individually. Each instance of NN is supposed to have its own array of weights, randomly initialized inside the NN constructor:
NN::NN(const int numLayers,const int *lSz,const int AFT,const int OAF,const double initWtMag,
const int UEW,const double *extInitWt)
{
// set number of layers and their sizes
nl=numLayers;
ls=new int[nl];
for(int i=0;i<nl;i++) ls[i]=lSz[i];
// set other parameters
aft=AFT;
oaf=OAF;
binMid=0.0;
if(aft==0) binMid=0.5;
// allocate memory for output of each neuron
out = new double*[nl];
for(int i=0;i<nl;i++) out[i]=new double[ls[i]];
// allocate memory for weights (genes)
// w[lr #][neuron # in this lr][input # = neuron # in prev lr]
w = new double**[nl];
for(int i=1;i<nl;i++) w[i]=new double*[ls[i]];
for(int i=1;i<nl;i++) // for each layer except input
for(int j=0;j<ls[i];j++) // for each neuron in current layer
w[i][j]=new double[ls[i-1]+1]; // w[][][ls[]] is bias
// seed and assign random weights (genes)
SYSTEMTIME tStart,tCurr;
GetSystemTime(&tStart);
for(;;)
{
GetSystemTime(&tCurr);
if(tCurr.wMilliseconds!=tStart.wMilliseconds) break;
}
srand(tCurr.wMilliseconds);
int iw=0;
for(int i=1;i<nl;i++) // for each layer except input
for(int j=0;j<ls[i];j++) // for each neuron in current layer
for(int k=0;k<=ls[i-1];k++) // for each input of curr neuron incl bias
if(UEW==0) w[i][j][k]=initWtMag*2.0*(rand()/(double)RAND_MAX-0.5);
else w[i][j][k]=extInitWt[iw++];
}
Sometimes its because you have a string of length x and you have accidentally put a longer word into it... thats what happened in my case.