I just started C++ recently and now I encounter a problem in a very simple program. I was successful inputting part_num and part_des (both type string), but the program skipped part_price and part_quant (type int). I could not enter values for these two last variables.How do I fix this problem? Thanks
#include <iostream>
using namespace std;
int main()
{
string part_num;
string part_des;
int part_price;
int part_quant;
cout<<"Please enter the part number: ";
cin>>part_num;
cout<<"\n"<<endl;
cout<<"Please enter the part description: ";
cin>>part_des;
cout<<"\n"<<endl;
cout<<"Please enter the part price: ";
cin>>part_price;
cout<<"\n"<<endl;
cout<<"Please enter the part quantity: ";
cin>>part_quant;
cout<<"\n"<<endl;
}
What Happens
Please test for yourself:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string my_string;
cout << "enter a string: ";
cin >> my_string;
cout << "you have entered: " << my_string << endl;
system("pause");
}
Results:
enter a string: one
you have entered: one
Press any key to continue . . .
enter a string: one two
you have entered: one
Press any key to continue . . .
Where is "two"? It remains in stream. When you try to get a number after this, this piece of text is automatically taken as your input, probably it rises an exception and your program suddenly ends.
How to Fix
Use something like getline.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string my_string;
cout << "enter a string: ";
getline (cin, my_string);
cout << "you have entered: " << my_string << endl;
system("pause");
}
This will eliminate the problem you're having.
enter a string: one two
you have entered: one two
Press any key to continue . . .
The code works fine. ( if you don't have whitespaces in there )
#include <iostream>
using namespace std;
int main()
{
string part_num;
string part_des;
int part_price;
int part_quant;
cout<<"Please enter the part number: ";
cin>>part_num;
cout<<"\n" << part_num <<endl;
cout<<"Please enter the part description: ";
cin>>part_des;
cout<<"\n" << part_des <<endl;
cout<<"Please enter the part price: ";
cin>>part_price;
cout<<"\n" << part_price <<endl;
cout<<"Please enter the part quantity: ";
cin>>part_quant;
cout<<"\n" << part_quant <<endl;
}
http://ideone.com/U31pb9
Just give yourself the output right away. To see what you were missing.
Fixed for whitespaces n stuff:
int main()
{
string part_num;
string part_des;
int part_price;
int part_quant;
cout<<"Please enter the part number: ";
getline( cin , part_num );
cout << "\n" << part_num <<endl;
cout<<"Please enter the part description: ";
getline( cin , part_des );
cout<< "\n" << part_des <<endl;
cout<<"Please enter the part price: ";
cin >> part_price;
cout << "\n" << part_price <<endl;
cout << "Please enter the part quantity: ";
cin >> part_quant;
cout << "\n" << part_quant <<endl;
}
Also think about using strings for the price and the quant as well and then convert them to integer if you want to keep using getline.
Try this, it should work:
#include <iostream>
using namespace std;
int main ()
{
int i;
cout << "Please enter an integer value: ";
cin >> i;
cout << "The value you entered is " << i;
cout << " and its double is " << i*2 << ".\n";
return 0;
}
Related
The user is prompted to "enter a middle initial". What happens if they enter a space, full name, or maybe a letter followed by a period '.' ?
How can we modify the program to handle this using cin.ignore?
This is the code I currently have:
I commented out the area I'm having trouble with.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string fname, lname;
char MI;
cout << "Please enter your first name: ";
cin >> fname;
cout << "Please enter your middle initial: ";
cin.ignore(1, '\n');
cin.get(MI);
cout << "Please enter your last name: ";
//cin.ignore('\n')
cin >> lname;
cout << "Your name is " << fname << " " << MI << " " << lname << endl;
return 0;
}
When I have this other cin.ignore in it still doesn't do anything and the last name reads the extra inputs. I've tried adding a number of characters to read and it still doesn't fix the problem. When I run it it just skips the input for last name. I also tried changing the last name input to getline but if still didn't do anything.
You can just use std::getline and std::istringstream:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string fname, lname;
std::string MI;
std::cout << "Please enter your first name: ";
std::getline(std::cin, fname);
std::istringstream iss(fname);
iss >> fname;
do
{
std::cout << "Please enter your middle initial: ";
std::getline(std::cin, MI);
} while (MI.size() != 1);
std::cout << "Please enter your last name: ";
std::cin >> lname;
std::cout << "Your name is " << fname << " " << MI << " " << lname << std::endl;
return 0;
}
Here for fname I have used std::getline to get user input and then I've used std::istringstream to get only one word of the input.
For MI I have made it a string and until and unless the user doesn't provide a single character, the program doesn't continue.
And the lname part is the same.
You should change:
cin.ignore(1, '\n');
cin.get(MI);
To simply:
cin >> MI;
Let operator>> ignore any white space, including line breaks, between the first name and the middle initial.
After reading MI, you can then use the following to ignore everything up to the next input:
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Try this:
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main ()
{
string fname, lname;
char MI;
cout << "Please enter your first name: ";
cin >> fname;
cout << "Please enter your middle initial: ";
cin >> MI;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter your last name: ";
cin >> lname;
cout << "Your name is " << fname << " " << MI << " " << lname << endl;
return 0;
}
I read some answers regarding how to fix it but I'm trying to also understand the concept behind it (i.e. why does the first getline work fine).
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int main(){
string ticker = "";
string date = "";
int pprice;
int sprice;
cout << "Enter the stock ticker =>" << endl;
getline(cin, ticker);
cout << "Enter the purchase price =>" << endl;
cin >> pprice;
IT WORKS FINE UNTIL IT GETS TO HERE:
cout << "Enter the sell date =>" << endl;
getline(cin, date);
cout << "Enter the sell price =>" << endl;
cin >> sprice;
cout << ticker << endl;
return 0;
}
/*OUTPUT:
Enter the stock ticker =>
XYZ
Enter the purchase price =>
12.34
Enter the sell date =>
Enter the sell price =>
12.34
XYZ
*/
You're probably not using cin.ignore() in the correct place. It should be used after std::cin and before getline().
For Example:
int x;
string y;
cin >> x;
cin.ignore(INT_MAX);
getline(cin, y);
The idea is to remove the carriage returns, newlines etc that cin leaves behind on the stream which cause getline() to immediate take and return.
//program8.cpp
#include <iostream>
#include "species.h"
#include "reptilian.h"
#include "mammalian.h"
#include "insects.h"
using namespace std;
void VirtualPrint(species &typeofSpecies){
typeofSpecies.printme();
}
void VirtualDanger(species &typeofSpecies){
typeofSpecies.showDanger();
}
int main(int argv, char **args){
reptilian rep;
insects ins;
VirtualPrint(rep);
VirtualPrint(ins);
VirtualDanger(rep);
VirtualDanger(ins);
return 1;
}
//species.h
#ifndef SPECIES_H
#define SPECIES_H
#include <iostream>
#include <string>
using namespace std;
class species{
public:
species();
virtual void printme();
virtual void showDanger() = 0;
protected:
string name;
string color;
int lifeExp;
bool thr;
};
#endif
//species.cpp
#include <iostream>
#include <string>
#include "species.h"
using namespace std;
species::species(){
cout << "Please enter name of species:" << endl;
getline(cin, name);
cout << "Please enter color of species:" << endl;
getline(cin, color);
cout << "Please enter life expectancy of species in years:" << endl;
cin >> lifeExp;
cout << "Please enter if species is threat:true(1) or false(0)" << endl;
cin >> thr;
}
void species::printme(){
cout << "Name: " << name << " Color: " << color << " Life Expectancy: " << lifeExp << " Threat: " << thr << endl;
}
//reptilian.h
#ifndef REPTILIAN_H
#define REPTILIAN_H
#include <iostream>
#include <string>
#include "species.h"
using namespace std;
class reptilian : public species{
public:
reptilian();
virtual void printme();
virtual void showDanger();
protected:
int length;
int lethality;
};
#endif
//reptilian.cpp
#include <iostream>
#include "reptilian.h"
using namespace std;
reptilian::reptilian(){
cout << "Please enter length(inches): " << endl;
cin >> length;
cout << "Please enter lethality(0-100): " << endl;
cin >> lethality;
}
void reptilian::printme(){
species::printme();
cout << " Length: " << length << " Lethality: " << lethality << endl;;
}
void reptilian::showDanger(){
cout << endl;
if(thr == true){
cout << "This species is a threat" << endl;
cout << "The name of the species is " << name << " has a color of " << color << ", has a life expectancy of " << lifeExp << " has a length of " << length << ", and a lethality of " << lethality << endl;
}
}
This is my code for my program it runs fine if one reptilian object is made. However when two are made it will not take the name of the second object. The same happens when two insects objects are made. I have not tested the mammalian object yet as I am trying to solve this problem first
edit:
output:
Please enter name of species:
sam
Please enter color of species:
orange
Please enter life expectancy of species in years:
100
Please enter if species is threat:true(1) or false(0)
0
Please enter length(inches):
60
Please enter lethality(0-100):
0
Please enter name of species:
Please enter color of species:
yellow
Please enter life expectancy of species in years:
20
Please enter if species is threat:true(1) or false(0)
0
Please enter length(inches):
10
Please enter lethality(0-100):
0
Please enter how venomous the species is(0-100):
0
Name: sam Color: orange Life Expectancy: 100 Threat: 0
Length: 60 Lethality: 0
Name: Color: yellow Life Expectancy: 20 Threat: 0
Length: 10 Lethality: 0
Venomous: 0
Your problem is mixing using getline with the >> operator. From http://en.cppreference.com/w/cpp/string/basic_string/getline:
When used immediately after whitespace-delimited input, e.g. after int n; std::cin >> n;, getline consumes the endline character left on the input stream by operator>>, and returns immediately. A common solution is to ignore all leftover characters on the line of input with cin.ignore(std::numeric_limits::max(), '\n'); before switching to line-oriented input.
So after the cin >> lethality a newline is left in the cin stream. The getline in the second instance of species sees this newline and immediately returns.
Also refer to this: std::cin:: and why a newline remains
To fix this, change your getline calls to use the cin >> method.
I have a very basic question. It's about extracting a value from a string input and then assigning this value to an int and then copying out this integer to screen.
Here is my code:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main ()
{
string mystr;
float price;
int quantity;
cout << "What is your name? ";
getline (cin,mystr);
cout << "Hello Mr. " << mystr << endl;
cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream (mystr) >> quantity;
cout << "Total price: " << quantity*price << endl;
cout << "Thank you for purchasing our product!";
return 0;
}
So the question is: when asked to enter price. Can I type "Price is 16" for example and the program is supposed to extract the 16 from the input and assign it to price?
If you allow that type of input, you would have to strip off the Price is portion before you can then read the 16 portion. Easiest way to do that is to simply put the input into a stringstream and call its >> operator in a loop until you reach a number or the end of the stream, eg:
cout << "Enter price: ";
getline(cin, mystr);
stringstream ss(mystr);
do
{
if (ss >> price)
break;
}
while (!ss.eof());
if (!ss)
{
// no price provided, do something...
}
I know this maybe such a wierd question but it stucks me for a couple of days ago. My assignemnt is to display the students' information and update them using STRUCT type. Here is my works:
#include <iostream>
using namespace std;
struct DATE
{
int day;
int month;
int year;
};
struct STUDENT{
char ID[8];
char name[50];
DATE birthday;
char address[100];
float Math;
float English;
float CS;
};
void inputClass(STUDENT* &list, int &n)
{
cout << "Please enter the number of students: ";
cin >> n;
list = new STUDENT[n+1];
for(int i=1; i<=n; i++)
{
cout << "Please enter the info of student " << i << endl;
cout << "ID: ";
cin >> (&list[i]) -> ID; //the same with "list[i].ID"
fflush(stdin);
cout << "Name: ";
cin >> (&list[i]) -> name;
fflush(stdin);
cout << "Date of Birth\n";
cout << "Day: ";
cin >> (&list[i]) -> birthday.day;
fflush(stdin);
cout << "Month: ";
cin >> (&list[i]) -> birthday.month;
fflush(stdin);
cout << "Year: ";
cin >> (&list[i]) -> birthday.year;
fflush(stdin);
cout << "Address: ";
cin >> (&list[i]) -> address;
fflush(stdin);
cout << "Math result: ";
cin >> (&list[i]) -> Math;
fflush(stdin);
cout << "English result: ";
cin >> (&list[i]) -> English;
fflush(stdin);
cout << "CS result: ";
cin >> (&list[i]) -> CS;
fflush(stdin);
cout << "************* Next Student *************\n" ;
}
}
void updateScore(STUDENT* list, int n)
{
cout << "Who do you want to update?" << endl;
cout << "Ordinal Number(s): ";
cin >> n;
//Display outdated results
cout << "Student's Name: " << (&list[n])-> name << endl;
cout << "*********** Current Results ***********" << endl;
cout << "Math: " << (&list[n]) -> Math << endl;
cout << "English: " << (&list[n]) -> English << endl;
cout << "CS: " << (&list[n]) -> CS << endl;
//Update results
cout << "Please update the results" << endl;
cout << "Math result: ";
cin >> (&list[n]) -> Math;
fflush(stdin);
cout << "English result: ";
cin >> (&list[n]) -> English;
fflush(stdin);
cout << "CS result: ";
cin >> (&list[]) -> CS;
fflush(stdin);
}
void main()
{
STUDENT* list;
int n;
inputClass(list, n);
updateScore(list, n);
}
In the "//Display outdated result" section, I used "cout" to print out the Name of the regarding student based on his/her ordinal numbers. However, let's say I want to get the whole name like: "John Smith". What I have got, however, is only "John". Is there a way I can get all of the characters?
Many thanks for your help and sorry for my bad English, I am a student from Vietnam.
Use std::getline from the <string> header, with a std::string variable, instead of >> and raw character array.
The >> reads whitespace-separated words of input.
The raw character array doesn't adjust to the needed length, and you risk Undefined Behavior on buffer overflow.
In passing, many/most programmers find all UPPERCASE to be an eyesore; it hurts the eyes.
Also, all uppercase is by convention (in C and C++) reserved for macro names.
As it's already been answered previously, you should use std::getline (refer to this question).
I'm assuming you're using a IDE, and it usually fixes a lot of things for us, users, but this may turn your code non-compilable in other compilers, so there are some things you should fix to be able to compile your code everywhere:
Always pay attention if you're adding the necessary includes. There's lack of an include statement for stdin and fflush. You should add:
#include <cstdio>
Also, main should return an int, so, it should have been something like
int main(int argc, char* argv[]){ /*Although you can usually omit the parameters*/
// Code
return 0;
}
By the way, just as a side comment, you forgot the subscript at:
cout << "CS result: ";
cin >> (&list[]) -> CS;