Using array from class in main function - c++

Consider the following code:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
class treasure
{
public:
char name[100];
double value[100];
double weight[100];
};
int itemNumber, totalWeight, i;
treasure item;
std::cout << "Enter total item weight: " << std::endl;
std::cin >> totalWeight;
std::cout << "Enter total item number: " << std::endl;
std::cin >> itemNumber;
for( i = 0; i < itemNumber; i++)
{
std::cout << "Enter item name: " << std::endl;
std::cin >> item.name[i];
}
return 0;
}
I wanted to input 5 item in the array but it is just asking for two item. It takes one item at first and then after printing three lines again takes another input. What seems to be the problem. What did went wrong?

char name[100]; means that you can save up to 100 items of type char, not 100 strings.
An important effect here is that your input is buffered. std::cin >> item.name[i]; takes one char from the input buffer and writes it to name[i]. The rest of your input remains in the buffer and will be used for the next execution of cin, i.e. the next execution of the same code line.
So if you enter e.g. 'abc' it saves 'a' to item.name[0], 'b' to item.name[1] and 'c' to item.name[2]. For item.name[3] the input buffer is empty so it waits for your next input.

Related

C++ Loop for String

I am struggling to create a loop for getting input from user. The input must push_back() each instance.
#include <iostream>
#include <array>
#include <cstring>
#include <vector>
#include <string>
#include <string.h>
using namespace std;
int main()
{
vector <string> bookQ = { "what","book","is","that","you","are","reading" };
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
string input;
int x = 0;
for (x != '1') { // require a loop to input string and end when user prompts
cout << "Enter 1 to stop" << endl; //
cin >> x; //
getline(cin, input); //
bookQ.push_back(input); //
} //
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}
Your for loop is missing the declaration and (iteration) expression parts:
for (declaration-or-expression; declaration-or-expression; expression)
so it should have looked like this:
for (;x != '1';) {
which is generally written as
while (x != '1') {
That would cause problems though since it would not stop directly when the user entered 1.
You are also comparing an int with a char ('1'), so in order to exit the loop, the user would have had to enter 49 (the ASCII value for 1), not 1.
You are also mixing formatted input (cin >> x) with unformatted input (getline). I suggest that you stick to one only.
Example:
while(cout << "Enter 1 to stop\n", getline(cin, input) && input != "1") {
bookQ.push_back(input);
}
Assuming you meant that input is a string, then you've made a few mistakes with types. First of all, you've used wrong type for variable x, you used int which is integer type, and the type string is required. Secondly, when comparing x with '1' you used single quotes, which define the type of variable as char, not string. To make 1 a string you should use double quotes, like so "1". Besides that, you have used for(condition), which is incorrect syntax. You should use while(condition). Also, when your loop iterates, the x variable is the input book name, and input variable is always an empty string, so I would suggest replace input with x everywhere. The working code is below.
P.S. I am not sure whether you want "1" to be in the final vector, so I haven't changed that
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<string> bookQ = {"what", "book", "is", "that", "you", "are", "reading"};
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
string input;
string x;
while (x != "1") {
cout << "Enter 1 to stop" << endl;
cin >> x;
bookQ.push_back(x);
}
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}
simply check if input is 1 everytime the user enters somthing, and when it does = 1, simply break loop.
string x;
while (true) { // require a loop to input string and end when user prompts
cout << "Enter 1 to stop" << endl;
cin >> x;
if (x == "1"){
break;
}
getline(cin, x);
bookQ.push_back(x);
}
}
First, your for syntax is wrong. You want a while loop instead, or in this case a do..while loop would make more sense. Also, you are pushing the user's input into the vector before validating what the input actually is.
Second, x is an integer, but '1' is a character whose ASCII value is number 49. Your loop will never end, because != will always be true. Since you want the user to enter number 1 to stop the loop, you need to drop the quotes:
Third, what is the point of pre-populating bookQ? Just declare the bookQ without any initial data, and then cout the entire question as a normal string. This way, after the user is done entering input, the vector will contain only the user's input and nothing else.
Try something more like this:
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
vector <string> bookQ;
string input;
cout << "what book is that you are reading" << endl;
do {
cout << "Enter a book, or 1 to stop" << endl;
getline(cin >> ws, input);
if (input == "1") break;
bookQ.push_back(input);
}
while (true);
for (size_t i = 0; i < bookQ.size(); ++i) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}

Program is not asking 3 questions and uses my answer to the first question for the other two

I am trying to ask the user to enter the names of 3 of their friends, however, it only asks one question and writes the answer from my first one in the second and third.
#include <iostream>
using namespace std;
int main()
{
char first_name;
cout << "Please enter a name: ";
cin >> first_name;
cout << first_name << endl;
char second_name;
cout << "Please enter a name: ";
cin >> second_name;
cout << second_name << endl;
char third_name;
cout << "Please enter a name: ";
cin >> third_name;
cout << third_name << endl;
return 0;
}
You should probably be using string in your code to take the input of names. In names you are probably passing more than one character. The first one is read by first_name and any further character will be read by the following character, specifically cin>>second_name and cin>>third_name would read the 2nd and 3rd character of your input.
char a;
char b;
cin>>a; //will only read one character and stop
cin>>b; //will read the second character of the input...
//be that after pressing enter(a Enter b) or continuous input (ab)
cout<<a<<" "<<b; //will output 1st and 2nd character only
This will happen even if you don't press the Enter key explicitly and this is why your program uses the answer of first question(which is probably more than 1 character since it is a name) in your code as the answer to 2nd and 3rd questions as well.
So for your purpose, you are better of using string to take input from the users.
Hope this clears your doubt !
You tried to hold a lot of chars (one word) in one char who can hold only one char.
#include <iostream>
#include <string> // We need a string, container to hold a chars. Something like array of chars but have a few difference.
using namespace std; // You should avoid using this but in that short code this doesn't matter
int main()
{
// You don't need separate container for this code
// Then we create one container to holds all of inputs
string input;
cout << "Please enter a name: ";
cin >> input; // Put input from user in our input(string)
cout << input << endl; // Print input
// Next code is the same as above
cout << "Please enter a name: ";
cin >> input;
cout << input << endl;
cout << "Please enter a name: ";
cin >> input;
cout << input << endl;
return 0;
}
I special avoided a few elements like using function because this must be simple as possible.

Converting string to number when using getline()

I've picked up a book on C++ and I'm basically at the very beginning of it (just started). For some of the problems I had to solve within the book I used the input stream cin the following way -->
cin >> insterVariableNameHere;
But then I did some research and found out the cin can cause a lot of problems, and so found out about the function getline() within the header file sstream.
I'm just having some trouble trying to wrap my head around what's happening in the following code. I don't see anything that uses the extraction operator (>>) to store the number value in. Its (my problem) further explained in the comments I left.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
// Program that allows a user to change the value stored in an element in an array
int main()
{
string input = "";
const int ARRAY_LENGTH = 5;
int MyNumbers[ARRAY_LENGTH] = { 0 };
// WHERE THE CONFUSION STARTS
cout << "Enter index of the element to be changed: ";
int nElementIndex = 0;
while (true) {
getline(cin, input); // Okay so here its extracting data from the input stream cin and storing it in input
stringstream myStream(input); // I have no idea whats happening here, probably where it converts string to number
if (myStream >> nElementIndex) // In no preceding line does it actually extract anything from input and store it in nElementIndex ?
break; // Stops the loop
cout << "Invalid number, try again" << endl;
}
// WHERE THE CONFUSION ENDS
cout << "Enter new value for element " << nElementIndex + 1 << " at index " << nElementIndex << ":";
cin >> MyNumbers[nElementIndex];
cout << "\nThe new value for element " << nElementIndex + 1 << " is " << MyNumbers[nElementIndex] << "\n";
cin.get();
return 0;
}
stringstream myStream(input): Creates a new stream that uses the string in input as "input stream" so to speak.
if(myStream >> nElementIndex) {...): Extracts number from the stringstream created using the line above into nElementIndex and executes ... because the expression returns myStream, which should be non-zero.
You were probably confused by using the extraction as the condition in the if statement. The above should be equivalent to:
myStream>>nElementIndex; // extract nElement Index from myStream
if(myStream)
{
....
}
What you probably wanted was
myStream>>nElementIndex; // extract nElement Index from myStream
if(nElementIndex)
{
....
}

Unable to read char array using cin.getline

We were asked to create a class which did the following:
Input int ecode, char ename and basicpay
Now in class, we had to calculate net_pay = basicpay*11/10
Lastly, we had to output ecode, ename and net_pay.
The question stated that net_pay variable cannot be created, its value only has to be used for output, and that value had to be calculated using a separate member function calc
Here is my code:
// Class employee
#include <iostream>
#include <cstdio>
using std::cin;
using std::cout;
class emp {
int ecode;
char ename[20];
float basic_pay;
public:
void input() {
cin >> ecode;
cin.ignore();
cin.getline( ename, 20); // <-- PROBLEM HERE
cin >> basic_pay;
}
float calc( float x) {
return x+x/10;
}
void output() {
cout << "\n Emp. code: " << ecode;
cout << "\n Emp. name: " << ename;
cout << "\n Emp. basic pay: " << basic_pay;
cout << "\n Emp. net pay: " << calc( basic_pay);
}
};
int main() {
emp e1;
cout << "Enter details of employee:\n";
e1.input();
cout << "\nUpdated Profile:\n";
e1.output();
return 0;
}
Error
I am frustrated from past hour about this problem with cin.getline.
String size < 20
The code is working fine for input string size less than 20, so I don't need cin.ignore(), and if I use it, cin.ignore is removing a first digit of basic_pay:
See images: Both are for small string input. Second one is with cin.ignore()
Notice below: Basic_pay was 1100, but it ignored 1.
String size > 20
If I input a string with char number greater than 20, then the overflowing char goes to float, and creates error. So to counter this, I need a cin.ignore(), but even that is not working!
Question
I am in a dilemma. For one string size, cin.ignore() is problamatic, but for other it has no effect. What to use, what not to use? Both are creating mutual conflict. Help me please!
cin.getline(name, 20) can only get 19 characters (one is reserved for the '\0'), therefore if someone inputs 20 or more, then cin.getline(name, 20) will fail, and the next cin >> basic_pay will fail too since the stream error flags are still set, you need to clear them with cin.clear().
Fix:
#include <limits> // for numeric_limits
if (!cin.getline(ename, 20)) // <-- PROBLEM HERE
{
std::cout << "Name too long, trimmed to: " << ename << std::endl;
// clear the stream error flags and ignore rest of the line
cin.clear();
cin.ignore(std::numeric_limits<int>::max(), '\n');
}
// now this line will not fail
cin >> basic_pay;
Live Demo

How to display the name from the array name?

I'm trying to study c++ about array
and I'm having a problem displaying the name from the array name
Because when I try to display the name of the passenger based on where he seat
the first letter becomes the last letter of his name..ahmm
Here's my code
#include <iostream.h>
#include <conio.h>
char* name[10]={" "};
int* seat=0;
char* pname="The Passenger is: ";
char ask;
void display();
int main()
{
clrscr();
cout<<"The Entering of name and seat number..."<<endl;
do
{
cout<<"\nEnter your name: ";
cin>>*name;
cout<<"Enter your seat number: ";
cin>>*seat;
cout<<"Do you want to input again?(Y/N): ";
cin>>ask;
}
while(ask=='y'||ask=='Y');
cout<<"\nDo you want to see the passenger's name?(Y/N): ";
cin>>ask;
if(ask=='y'||ask=='Y')
{
cout<<"\nThe Program will now direct you to the displaying of passenger's name...."<<endl;
display();
}
else
{
cout<<"\n\nThe Program will end shortly....";
}
getch();
return 0;
}
void display()
{
do
{
cout<<"\nEnter seat number to display passenger's name: ";
cin>>*seat;
cout<<pname<<*name[*seat-1]<<endl;
cout<<"Do you want to try again?(Y/N): ";
cin>>ask;
}
while(ask=='y'||ask=='Y');
cout<<"\nThe Program will now end shortly....";
getch();
}
To display the name from the array name you have at first to define the array correctly.:)
If you do not know yet about standard class std::string then the array should be defined as for example
char name[10][20];
that is it can store 10 names that have length no more than 20 characters.
Or if you know about class std:string then you can define it as
#include <string>
std::string name[10];
And it would be even better to define
#include <string>
#include <array>
std::array<std::string, 10> name;
For this program neither pointer is needed to be defined.
Take into account that when you ask to enter a seat number you should check that this number is in the range 1 - 10 (in this case you will need to decrease it by one when will use it to access the array) or 0 - 9.
You seem to be having a problem with pointers. Namely
int* seat=0;
will not allocate space for the integer, but instead allocate space for a pointer and then set this pointer and set it to address 0. When you perform
cin>>*seat;
Your program attempts to dereference the pointer which does not point to anything. Furthermore when you perform
cin >>*name
You are not writing to the whole string but instead writing to the dereference location, namely the first character of the string.
For a start change
int* seat=0;
to
int seat = 0
and
cin>>*name;
to
cin>>name;
good luck!
Edit:
also you want to change the:
cin >> *seat;
to
cin >> seat
Nevertheless you might need some more practice in the basic language features, like pointers, you could use some existing data structures. Since you are using cout and cin i assume your compiler supports the C++ standard library. I would use a map, to save the passengers.
#include <iostream>
#include <map>
struct passenger
{
char name[10];
};
std::map<int, passenger> passengers;
int seat;
char ask;
void display();
int main()
{
std::cout<< "The Entering of name and seat number..." << std::endl;
do
{
passenger p;
std::cout << "\nEnter your name: ";
std::cin >> p.name;
std::cout << "Enter your seat number: ";
std::cin >> seat;
// add passenger to the map
passengers.insert(std::pair<int, passenger>(seat, p));
std::cout << "Do you want to input again?(Y/N): ";
std::cin >> ask;
}
while(ask=='y'||ask=='Y');
std::cout << "\nDo you want to see the passenger's name?(Y/N): ";
std::cin >> ask;
if(ask=='y' || ask=='Y')
{
std::cout << "\nThe Program will now direct you to the displaying of passenger's name...." << std::endl;
display();
}
return 0;
}
void display()
{
do
{
std::cout << "\nEnter seat number to display passenger's name: ";
std::cin >> seat;
// check if passenger data is available for this seat
if(passengers.find(seat) != passengers.end()) {
std::cout << "The Passenger is: " << passengers[seat].name << std::endl;
} else {
std::cout << "Seat still available ..." << std::endl;
}
std::cout << "Do you want to try again?(Y/N): ";
std::cin >> ask;
}
while(ask=='y' || ask=='Y');
}
If you are using a pointer *seat you don't have to access it as
cin>>*seat. You only need to write cin>>seat.
While you are learning cpp, check out what pointers are too.
Here's a little info on that too, though that is not exactly the subject matter,
int *S; // pointer of type int
int x; // variable of type int
S = &x; // pointer S is now pointing to memory location of x
S = 4;
OR
x = 4; // changes the contents of memory location to which S points`
cout << *S; // displays the memory address to which S points i.e.
x