First letter in string output not showing

Hi, i made a simple oop program in which i ask user to input some values and then print them. The problem is, the first letter of the first string is not showing in the output. Here's the output:

https://i.ibb.co/dQbNYxF/vvmnbmn.png



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  #include<iostream>
#include<string>

using namespace std;
class Notebook{
	public:
	int bookid;
	string bookname;
	int bookprice;
	int num;
	Notebook(){
		cout<<"Enter details." <<endl <<"***************"<<endl;
		cout<<"Enter book name:\t";
		cin.ignore();
		getline(cin,bookname);
		cout<<"Enter book id:\t";
		cin>>bookid;	
		cout<<"Enter book price:\t";
		cin>> bookprice;
	}
	
	void display(){
		cout<<"The book id is:\t" <<bookid <<"\nThe book name is:\t" <<bookname <<"\nThe book price is:\t" <<bookprice <<endl;
		
	}
		
};

int main(){
	Notebook b1,b2;
	b1.display();
	b2.display();
	
}
Last edited on
Did you accidentally copy/paste twice?

The very first cin operation that runs here will be ignore(), which discards one character from your input, waiting for input if it needs do. Thus, that first character never gets read into into one of your notebooks.

As for why the second one works, there'll still be a newline character left in your input from when you hit Enter after putting in the book price.

-Albatross

Last edited on
yes, sorry. but where do I put cin.ignore(), then?
Depends on what you're trying to do with it. If it's to get rid of the newline that you have after entering the book price... why not just put it after the code that reads in the book price?

Otherwise, a more kosher solution for what you're trying to do might be to just use std::getline and a std::string in your constructor to get the lines that contain the book id and price, then then convert the string with stoi, like so:
1
2
3
4
std::string buffer;
std::cout << "Reading the book id:\t";
std::getline(std::cin, buffer);
bookid = std::stoi(buffer);


-Albatross
Hello zeplik,

Good job on using code tags.

In addition to what Albatross has said, this is what i noticed.

What is the point of the class? You have made everything public which defeats the purpose of the class. You need to move line 6 to line 11.

In the ctor you do not need the "ignore" before the "getline" as there is nothing to ignore at this point. But you do need an "ignore" after your last formatted input, i.e., cin>> bookprice; as the new line will be left in the input buffer for the next "getline" to extract.

The use of std::cin.ignore() will use the default values of one character or the new line whichever comes first. This may work here for now, but not a good idea for the future. The more preferred use if "ignore" is:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>. . This is a more portable code as different operating systems and header files could have a different value for "max" and this will use what is designed by the header files.

Making the variables "private" is not a problem as the two functions are member functions of the class and have access to private variables.

Looking at the variables the "std::string" for "bookName" is fine and no it is not a type just a more acceptable way of naming the variable although it is not required and you can name a variable any way you want.

Not knowing what "bookId" should be this could be a problem if the number is greater than what an "int" can store. You may want to consider using an "unsigned long" or "unsigned long long" for this.

For "bookPrice" an "int" can be used, but it will take more work. For what you are doing a "double" is a better choice.

In the future it would be a good idea to give an example of the values for each variable so others can see what you are doing.

The following code is one possible fix for your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<iostream>
#include <limits>
#include<string>

//using namespace std;  // <--- Best not to use.
using std::cin; // <--- Better choice.
using std::cout;
using std::endl;
using std::getline;
using std::string;

class Notebook
{
	private:
		int bookid;
		string bookname;
		int bookprice;
		int num; // <--- Does this have a use?

	public:
		Notebook()
		{
			cout << "\nEnter details." << '\n' << "***************" << endl;
			cout << "Enter book name: ";

			getline(cin, bookname);

			cout << "Enter book id: ";
			cin >> bookid;

			cout << "Enter book price: ";
			cin >> bookprice;

			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
		}

		void display()
		{
			cout << "\n\nThe book id is: " << bookid
				<< "\nThe book name is: " << bookname
				<< "\nThe book price is: " << bookprice
				<< endl;
		}
};

int main()
{
	Notebook b1, b2;

	b1.display();
	b2.display();

	// The next line may not be needid. If you have to press enter to see the prompt it is not needed.
	//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue: ";
	std::cin.get();

	return 0;
}

A class is "private" by default, so line 14 is not needed. I put it there as an example.

Lines 23 - 34 I have changed. Using the "\t" may seem like a good idea, but do not count on it to line up your output. Depending on what precedes the "\t" the tab could be one or two spaces or a proper tab. Also putting the input that far away from the prompt just looks bad.

Mixing a "std::getline" and formatted input, (std::cin >> ??), does work although not as well as staying with one or the other. In your program when the ctor first runs the input buffer is empty, so there is no need to "ignore" anything. After the last "std::cin >>" there is a new line that needs to be cleared before the next "std::getline" is used.

Adding the blank lines just makes the code easier to read and understand. This also applies to the output to the screen as you can see in the "display" function.

It is not necessary what I did with the "display" function, but I wanted to show you a different way of doing this. I does make it easier to read and edit.

Also notice the use of the "\n"s and the removal of the "\t"s. Just like for input the "\t"s can work against you. For better formatting of the output include the header file "<iomanip>" and use "std::setw()". If you are not ready for this no worries.

In main the lines before the "return" you may not need. I use them to create a pause before the console window closed when the program reaches the "return".

The return is not necessary or required, but it does make a good break point in debugging if needed.

Your program is a very good start, but does need some fixing and could use some of the improvements I have put in.

Any questions about the code let me know,

Hope that helps,

Andy

Edit: typo
Last edited on
Thank you so much Andy, yes putting cin.ignore() after cin>>bookprice is indeed working and the program is running fine now. Also, thank you so much for taking the time and improving my code. I will surely keep in mind these instructions while creating next programs. Thanks again, man.
Last edited on
Topic archived. No new replies allowed.