Why is the Output is skipping statement of gets(&char*) - c++

In the code below I have a class called Market. With the data members and functions as shown. When the function shopkeeper(market &m , int i) is called , The compiler executes the the printing of "Name" and "Price" without taking the Name from user by gets().
class market
{
public:
char item;
double price, tax, total;
public:
market()
{
char* item;
price=0;
tax=0;
}
void shopkeeper(market &m, int i)
{
cout<<" Item number "<<i<<"\n ";
cout<<" ----------- "<<"\n";
cout<<"Name ";
gets(&(m.item));
cout<<" Price "<<endl;
cin>>m.price;
cout<<" Tax "<<endl;
cin>>m.tax;
}
The output us as follows:

item is a single char. If you read documentation of gets, that function receives a pointer to buffer you have to allocate, big enough to fit input, or an Undefined Behavior would happen.
Also, gets is a function which should no longer be used in C++. It also was removed from recent versions of language. You should use std::string and read it from std::cin like everything else.

Related

error: too few arguments to function 'float getTotalAmount'

Here is the problem i Designed a program to collect blood from users after collecting the data i give them the output. one of the output is retrieved from outside function which is getTotalAmount but i am getting error: too few arguments to function 'float getTotalAmount'. code attached below :
class BloodDonator{
private:
string bloodtype ,name;
float amount ;
public:
void set_details(){
cout<<"Enter Name :";
cin>>name;
cout<<"Please select a blood type ...\n";
cout<<" Enter [1] for A positive\n";
cout<<" Enter [2] for A negative\n";
cout<<" Enter [3] for B positive\n";
cout<<" Enter [4] for B negative\n";
cout<<" Enter [5] for O positive\n";
cout<<"Enter [6] for O negative\n";
cout<<"Enter [7] for AB positive\n";
cout<<"Enter [8] for AB negative\n";
cin>>bloodtype;
cout<<"Enter Amount (ml) :";
cin>>amount;
};
float getAmount(){
return amount;
};
string getName(){
return name;
};
string getBloodType(){
return bloodtype;
};
getTotalAmount(float &amount);
string n(){return name;}
};
float getTotalAmount(BloodDonator *ps)
{
static float totalamount=0;
totalamount = totalamount + ps->getAmount();
return totalamount;
};
int main()
{
BloodDonator p1 ;
//float getTotalAmount();
//getTotalAmount();
for(int i=0;i<3 ;i++){
cout<<" Input Details\n";
cout<<"------------------------------\n";
p1.set_details();
//p1.getTotalAmount(*p1.getAmount());
cout<<"------------------------------\n";
cout<<" output Details\n";
cout<<"------------------------------\n";
cout<<"name :"<<p1.n()<<endl;
cout<<"blood type :"<<p1 .getBloodType()<<endl;
cout<<"Blood Amount :"<<p1.getAmount()<<endl;
cout<<"Total Amount of Blood Donated so far :\n"<<getTotalAmount()<<endl;//here is total amount of blood
}
return 0 ;
}
You may have to change the following segments of your code:
// it's ok
cout<<"name :"<<p1.n()<<endl;
// removed space between "p1." and "getBloodType()"
cout<<"blood type :"<<p1.getBloodType()<<endl;
// it's ok
cout<<"Blood Amount :"<<p1.getAmount()<<endl;
// passed pointer to p1, cause getTotalAmount() expects a pointer to BloodDonator object.
cout<<"Total Amount of Blood Donated so far :\n"<<getTotalAmount(&p1)<<endl;
Your code has several more problems like:
What is the job of getTotalAmount(float &amount); inside BloodDonator class.
if BloodDonator has already getTotalAmount(float &amount);, then, why there is a float getTotalAmount(BloodDonator *ps) doing outside...
you're hardcoding blood donars detials, you should inject details through constructor...
etc...
Look at the declaration in the class:
getTotalAmount(float &amount);
And the call in main() (last cout statement):
getTotalAmount();
You need to pass a required pointer variable p1 (since that's relevant and compatible) to the getTotalAmount().
Also the explicit type is missing in the declaration, it defaults to int, beware of that. To prevent it, declare it correctly:
float getTotalAmount(float &amount);
Another problem, which is the definition of function. You've just declared a function getTotalAmount (non class member function), you actually didn't wrote definition of the class member function getTotalAmount, i.e. you've defined the same named functions in two places.
It's up to you to code only for the one required by you and delete the another. In the current code provided by you, the class member function getTotalAmount has no meaning.
There are a few problems but the fundamental issue is bad program design. Any time you use a static variable you should think hard whether you really need it. Especially as a beginner you will almost never really need to use static variables.
In your code you have a static variable inside getTotalAmount. Instead this variable should be in main (and non-static). And the calculation to add the total blood donated should also be in main. Like this
int main()
{
BloodDonator p1;
float totalAmount = 0.0f;
for (int i=0; i<3; i++) {
...
cout << "Blood Amount :" << p1.getAmount() << endl;
totalAmount = totalAmount + p1.getAmount(); //here is total amount of blood
cout << "Total Amount of Blood Donated so far :\n" << totalAmount << endl;
}
The function getTotalAmount can be deleted.

why is the file not being created by f stream or even if it is the output is just garbage values?

I had to design a basic hospital management system by using Turbo C++ . everything seems to be working fine including the add record function but when i choose to view the records that were entered (through a main menu that was created using the same program) the function just starts displaying an infinite loop of random characters. moreover i can't seem to find the file that was created in C:\TurboC++\Disk\TurboC3\BIN.
I think that perhaps the problem arises because the file was not created and there may be another file with the same name as of the class.
p.s. i know that i am using an ancient relic so you don't need to mention that and its my first semester so i am still not aware with all the technical stuff so would very much appreciate if you kept the language as simple as possible to help me and others like me.
class hospital {
int bill,
ref,
age;
char disease[30],
name[20],
doctor[20],
address[50],
sex;
public : void getdata() {
cout<<"ENTER THE NAME OF THE PATIENT"<<endl;
gets(name);
cout<<endl<<"ENTER THE ADDRESS OF THE PATIENT"<<endl;
gets(address);
cout<<endl<<"ENTER THE NAME OF THE DIESEASE(S) OF THE PATIENT"<<endl;
gets(disease);
cout<<endl<<"ENTER THE SEX OF THE PATIENT(f/m)"<<endl;
cin>>sex;
cout<<endl<<"ENTER THE NAME OF THE DOCTOR"<<endl;
gets(doctor);
cout<<endl<<"ENTER THE PRESCRIPTION/REFERENCE no."<<endl;
cin>>ref;
cout<<endl<<"ENTER THE AGE OF THE PATIENT"<<endl;
cin>>age;
cout<<endl<<"ENTER THE BILL OF THE PATIENT"<<endl;
cin>>bill;
}
void display() {
cout<<endl<<"THE DETAILS OF THE PATIENT ARE AS FOLLOWS:"<<endl;
cout<<"AGE:"<<age<<"\tREFERENCE/PRESCRIPTION no.:"<<ref;
cout<<"\tTHE NAME OF PATIENT:";
puts(name);
cout<<endl<<"\tTHE NAME OF THE DOCTOR:";
puts(doctor);
cout<<endl<<"\tTHE DIAGNOSED/TESTED FOR DISEASE(S) IS/ARE :"<<endl;
puts(disease);
cout<<endl<<"THE SEX OF THE PATIENT IS "<<sex<<endl;
cout<<endl<<"THE BILL OF THE PATIENT IS "<<bill<<endl;
cout<<endl<<"THE ADDRESS OF THE PATIENT IS: "<<endl;
puts(address);
}
int retref() {
return ref;
}
}
;
void main() {
clrscr();
hospital h;
cout<<endl<<"\n\n\t\t\tLOADING...\n\t\tPLEASE WAIT..\n";
system("pause");
clrscr();
cout<<endl<<"\tWELCOME TO THE HOSPITAL MANAGEMENT SYSTEM"<<endl;
displayrec();
getch();
}
this is the function to view all the records that were saved
void displayrec()
{
hospital h;
ifstream fin;
fin.open("hospitalrecords.dat", ios: :binary);
while(!fin.eof()) {
h.display();
if(fin.eof()) break;
}
}
You don't read anything from the file, so eof() will always be false, leading to an infinite loop.
You need to actually read something in the loop, and initialize h with the data you read.

How would I go on as to "return" string arrays between functions?

Hey so I was experimenting what I knew and realized when I tried passing a string value with return it wasn't supported, any idea? Sorry if my code is noob style (I only have 2 months of experience), I was planning on splitting the code between functions but I can't seem to do it because returning my array of strings cant be done with return :( Here's the code:
#include <iostream>
#include <math.h>
#include <sstream>
using namespace std;
int itemlist=0;
int c=0;
int r = 0;
int itemlistdec()
{
cout<<"How many items would you like to input?";
cin>>itemlist;
return itemlist;
}
int main() {
itemlistdec();
string item[4][itemlist];//declares item and that columns equal to itemlist whose content is declared right above
for (int c=0;c<itemlist;c++)
{
for (int r=0;r<3;r++) //DETERMINES WHERE EACH RECORD GOES
{
if (r==0)
{
cout<<"Please enter the name of the item ";
}
if (r==1)
{
cout<<"Please input the buying price\n";
}
if (r==2)
{
cout<<"Please input the selling price\n";
}
cin>>item[r][c];
}
}
int calc[3][itemlist];//declaring calc and itemlist
for (int r = 0;r<itemlist;r++)
{
istringstream(item[1][r])>>calc[0][r]; //TAKES BUYING PRICE INTO INT ARRAY FOR CALCULATION
}
for (int r = 0;r<itemlist;r++)
{
istringstream(item[2][r])>>calc[1][r]; //TAKES SELLING PRICE INTO INT ARRAY FOR CALCULATION
}
for (int fart = 0;fart<itemlist;fart++)
{
calc[2][fart] = calc[1][fart] - calc[0][fart]; //REPEATS CALCULATION FOR PROFIT UNTIL ITEMLIST IS REACHED
}
for (int r = 0;r<itemlist;r++)
{
stringstream ss;
ss<<calc[2][r]; //CONVERTS BOTH PROFIT VALUES INTO STRINGS
item[3][r] = ss.str();
}
cout<<"______________________________________________\n"; //DISPLAYS OUTPUT IN TABLE FORM
cout<<"Item\t\tBuying Price\t\tSelling Price\t\tProfit\n";
for (int c=0;c<itemlist;c++)
{
for (int r=0;r<4;r++)
{
cout<<item[r][c]<<"\t\t";
if (r==1)
{
cout<<"\t";
}
if (r==2)
{
cout<<"\t";
}
if (r==3)
{
cout<<"\n";
}
}
}
return 0;
}
I think you can use vector, it's very powerful. Like that:
std::vector<std::vector<std::string> > mySecondVector;
std::vector<std::string> myFirstVector;
myFirstVector.push_back("MyString");
mySecondVector.push_back(myFirstVector);
mySecondVector[i][j]; // to access
And for add, access to an element watch on http://www.cplusplus.com/reference/vector/vector/
Returning an array is a bit goofy. you have to return it as a pointer, and as soon as you do that you lose all size information. You have this handled by itemlist hanging around as a global variable, but global variables impose their own set of limitations. For one, you can never have more than one of these arrays (unless they are all the same size) because multiple arrays would be storing their length in the same spot.
First you have to flip the orientation of the array to get the constant size on the right-most index. Frankly because of locality (all of the data with respect to one item is in the same memory region, so if you load one part of an item into cache you probably load all of it. This almost always results in a much faster program) it's probably better that way, anyway. Then you've probably noticed you can't just return string[][] or anything that looks like it without the compiler barking at you, so you have to play games defining custom data types that you can return.
typedef string (*arrayPtr)[4];
Now you could try
arrayPtr itemlistdec()
{
cout << "How many items would you like to input?";
cin >> itemlist;
string item[itemlist][4];
//load the array
return item;
}
And itemlist knows how big the array is, but you get a new snag. Item goes out of scope on you and is no longer valid. Even more fun, string item[itemlist][4]; isn't even legal C++ because itemlist isn't a constant value. It works as a convenience in some C++ compilers, but not all.
So how about this? Dynamic allocation of the array will make it outlive itemlistdec, but now you'll have to delete the array manually when you are done with it.
arrayPtr itemlistdec()
{
cout << "How many items would you like to input?";
cin >> itemlist;
arrayPtr item = new string[itemlist][4];
//load the array
return item;
}
Now we've got something that works. We can make it a bit more readable (and less at the same time, because a reader has to track down just what an array is in order to know how to use it) by
typedef string (array)[4];
typedef array (*arrayPtr);
arrayPtr itemlistdec()
{
cout << "How many items would you like to input?";
cin >> itemlist;
arrayPtr item = new array[itemlist];
//load the array
return item;
}
This does not extend to variable length on both dimensions or if you absolutely must have the constant on the inside index. For that case you need this bastich:
string ** itemlistdec()
{
cout << "How many items would you like to input?";
cin >> itemlist;
string** item = new string*[4]; // 4 can be any number, but you also have to
// use it in place of 4 in the for loop
for (size_t index = 0; index < 4; index++)
{
item[index] = new string[itemlist];
}
//load the array
return item;
}
Doable, but you now have picked up a bunch of memory management duties. All of the allocated memory must be released with delete[]. In the string ** case, you have to run through the left-most index and delete[] all of the right-most arrays before deleting the left-most.
You can eliminate this with vector<vector<string>>, but in this case it's ugly. Great trick, but doesn't fit the overall program goal.
vector<vector<string>> itemlistdec()
{
int itemlist;
cout << "How many items would you like to input?";
cin >> itemlist;
vector<vector<string>> item(4, vector<string>(itemlist));
for (int c=0;c<itemlist;c++)
{
cout<<"Please enter the name of the item ";
cin>>item[0][c];
cout<<"Please input the buying price\n";
cin>>item[1][c];
cout<<"Please input the selling price\n";
cin>>item[2][c];
}
return item;
}
Note I'm returning the local vector and counting on move semantics to move the vector on return rather than copying it. Also note that you don't need a global itemlist anymore because the vector knows how big it is. You can even add stuff to it later if you want. And also note I ditched the inner for loop on the input. It's not needed.
This works better than the array options, but I still don't like it. Item is calling out for its own class so we can take advantages of the goodies that object oriented programming brings. We can also the correct data types for all of the member variables. That way we can catch bad input as the user enters it and get rid of an extra integer array used by the calculation.
class Item
{
public:
void read(istream & in)
{
// ignoring possibility of total failure of cin here.
cout<<"Please enter the name of the item ";
in >> name;
cout<<"Please input the buying price\n";
while (!(in >> buyPrice)) // loop until we read an integer from the user.
{
in.clear();
cout<<"Invalid. Please input the buying price\n";
}
cout<<"Please input the selling price\n";
while (!(in >> sellPrice))
{
in.clear();
cout<<"Invalid. Please input the selling price\n";
}
return in;
}
// calc logic method goes here.
// output method goes here.
private:
string name;
int buyPrice; // no screwing around with the calc array. numbers are
//read in as numbers or the input fails
int sellPrice;
};
vector<Item> itemlistdec()
{
int nrItems = 0;
cout << "How many items would you like to input?";
cin >> nrItems;
vector<Item> itemlist(nrItems);
for (Item& item : itemlist)
{
item.read(cin);
}
return itemlist;
}
Note I'm not checking validity of all input, just that valid integers were used. Probably sufficient, but ehhhh.... I have accidentally closed stdin by mistake. Not a fun thing to debug. Anyway, you have worse problems if stdin is going down.

how can i put string after int in c++

i want to create a c++ program like that
Design and implement using C++, a class "Student" that stores the student id, name,
40
address and marks in five different subjects (in an array having five elements). Assume
that marks are out of 100. The class should have a constructor, a member function for
input of marks and an additional member functions which prints the student details
and marks, along with total marks and percentage. Write the main function which
creates two such student objects and displays their details
i want to insert student name and marks in this program but i am getting error why ...
this is my program..
please provide solution with example
#include <iostream>
#include<stdio.h>
using namespace std;
class student{
private:
int id;
char *name;
int marks[5];
char *address;
public:
student();
void input_detail();
void display_detail();
double total_marks();
double percentage();
};
student::student(){
id=0;
name='\0';
marks[5]=NULL;
address='\0';
}
void student::input_detail(){
int i=1,j=0;
cout<<"please enter student id: "<<endl;
cin>>id;
cout<<"please enter student name: "<<endl;
gets(name);
for(i=1,j=0;i<6;i++,j++){
cout<<"enter marks "<<i<<" subject : "<<endl;
cin>>marks[j];
}
cout<<"please enter student address : "<<endl;
gets(address);
}
double student::total_marks(){
double total_marks;
int i=0;
for(i=0;i<5;i++){
total_marks=total_marks+marks[i];
}
return total_marks;
}
double student::percentage(){
double percentage;
percentage=total_marks()/500*100;
return percentage;
}
void student::display_detail(){
int i=1,j=0;
cout<<"student id: "<<id<<endl;
cout<<"student id: "<<name<<endl;
for(i=1,j=0;i<6;i++,j++){
cout<<"marks "<<i<<" subject : "<<marks[j]<<endl;
}
cout<<"student address : "<<address<<endl;
cout<<"student total marks : "<<total_marks()<<endl;
cout<<"student percentage : "<<percentage()<<endl;
}
int main()
{
student s1;
s1.input_detail();
s1.display_detail();
return 0;
}
i am getting this output
please enter student id:
anil
please enter student name:
please enter student address :
annn
student id: 0
student id: anil
student address : annn
student total marks : 1.1331e-317
student percentage : 0
Process returned 0 (0x0) execution time : 19.901 s
Press any key to continue.
but where is the student marks it is not showing in program
A quick check shows me two errors:
The for condition is the opposite of what you think: when it's true the loop continues, when it's false the loop quits. A loop like for(int i=0; i>6; i++){...} will never run because the condition is false when starting (0 is not bigger than 6).
When you declare double a variable in C++ you need to initialize it; this error is present when computing the sum (start with double total_marks=0).
There are indeed many other errors and questionable approaches, but those are probably better discussed in class...

Creating an employee class

I am attempting to write the following:
1) Write the class definition for a class named Employee with name and salary as employee objects. The class contains two member functions: the constructor and a function that allows a program to assign values to the data members.
2) Add two member functions to the Employee class. One member function should allow any program using an employee object to view the contents of the salary data member. The other member function should allow the program to view the contents of the employee name data member.
3) Add another member function to the Employeeclass. The member function should calculate an employee objects new salary, based on a raise percentage provided by the program using the object. Before calculating the raise, the member function should verify that the raise percentage is greater than or equal to zero. If the raise percentage is less than zero, the member function should display an error message.
4) Write a main function that will create an array of employee objects, assign
values to the objects, display the names and current salaries for all objects,
ask user for the raise percentage and then calculate and display new salaries
for all objects.
I have attempted this with the following code:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class EMPLOYEE
{
public:
EMPLOYEE();//
EMPLOYEE(string name, int salary);//
public:
string name;//name to be input
int salary;//salary to be input
public:
int enter_values();
int output_values();
int NEW_SALARY( int percentage_raise);
};
//default constructor
EMPLOYEE::EMPLOYEE()
{
name = "";
salary = 0;
}
//constructor with name/salary variables
EMPLOYEE::EMPLOYEE(string NAME, int SALARY)
{
name= NAME;
salary= SALARY;
}
//name and salary to be input...
int EMPLOYEE::enter_values()
{ cout<<"Enter name and salary: ";
cin>> name;
cin>>salary;
}
//output
int EMPLOYEE::output_values()
{ cout<<"Name: "<<name<<endl;
cout<<"Salary: "<<salary<<endl;
}
//
int EMPLOYEE::NEW_SALARY(int percentage_raise)
{
EMPLOYEE updated_salary;
if ( percentage_raise >= 0){salary= salary *(percentage_raise/100);
}
else if(percentage_raise< 0)
{ cout<<"Error Message"<<endl;
}
return percentage_raise;
}
int main()
{
EMPLOYEE employees[100];
EMPLOYEE.NEW_SALARY();
int percent= 0;
int i;
for(i =0 ;i<100 ; i++)
{ employees[i]=EMPLOYEE();
employees[i].enter_values();
employees[i].name;
employees[i].salary;
employees[i].output_values();
cout<<"How much should the salary be raised by?"<<endl;
cin>>percent;
cout<<EMPLOYEE.name<<"'s new salary is "<<percentage_raise<<endl;
}
}
However, I cannot access the parts I need to store the information into the array in the main function, nor can I apply the percentage raise when the program prompts the user.
I'm pretty sure I have syntax errors which I am unaware of. I'm not asking for someone to do everything for me, but I would appreciate a steer in the right direction. I don't quite understand classes and how to call them into different parts of a program. Thank you for your time.
You have almost everything in good order.
Things to fix:
The line
if ( percentage_raise >= 0){salary= salary *(percentage_raise/100);
will set salary to zero unless percentage_raise is greater than 100. That's because the expression (percentage_raise/100) will be an integer division and will evaluate to zero, unless pecentage_raise is greater than 100.
You can fix it with:
if ( percentage_raise >= 0)
{
int raise = (salary*percentage_raise)/100;
salary += raise;
}
The line
EMPLOYEE.NEW_SALARY();
is going to produce a compiler error since there is no object named EMPLOYEE.
You can safely remove that line. It's not serving any purpose.
You are missing a call to set the percentage raise after you read the input. You need the line
employees[i].NEW_SALARY(percent);
immediately after you read percent.
The following line is incorrect.
cout<<EMPLOYEE.name<<"'s new salary is "<<percentage_raise<<endl;
since there is no object named EMPLOYEE. You can replace it with:
cout<<employees[i].name<<"'s new salary is "<<employees[i].salary<<endl;
class Employee
{
public:
Employee();
int salary;
};
Employee::Employee() { salary = 10; }
int main()
{
Employee joe;
std::cout << "Joe Salary: " << joe.salary << std::endl;
joe.salary = 15;
std::cout << "Joe New Salary: " << joe.salary << std::endl;
}
Usually, you will want your data members to be private and use an accessor method to provide the values of the data members which, again, should be private.