Having to input twice in a loop (C++)

Hello! I'm a new user here, please forgive me for any future mistakes that i will do. I'm trying to create a program (based on an exam question as an exercise) where the user has to input their name and what the program ask them.My coding consist of repetition and selection , selection is inside the repetition, and the entire coding is repetition ( sentinel ) except for the menu.My problem is that when running it the first time everything is fine until it starts to loop, the input that ask's the user was not detected thus causing it to display "invalid code" ( since it is the last part of a selection ). I fixed it by typing another line of inserting the data in the variable, the program works fine but i have to input the data twice now. What is causing it to not detect the input after while statement here? (I am using while statement)

The rest of my classmates also have the same problem, and i also faced the same issue with another coding

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
  #include <iostream>
#include <cstring>
using namespace std;

int main()
{
	int workPrice, size , price , TOTprice = 0 , numOfTire ,earlyPrice;
	char serviceCode[5] ,brandCode,customerName[20],vehiclePlate[10],tyreBrand,answer='Y';
	string  serviceDesc;
	
	cout<<"                         Welcome tp SpeedTyre Service";
	cout<<"\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
	cout<<"\nService Offer:";
	cout<<"\nTC - Tyre change";
	cout<<"\nAl - Alignment";
	cout<<"\nBL - Balancing";
	cout<<"\nFor tyre change we provide three types of brand which are:";
	cout<<"\nB - Bridgestone\nM - Michelin";
	cout<<"\nEnter customer name:";
	cin.getline(customerName,20);
	cout<<"\nEnter vehicle plate no.:";
	cin.getline(vehiclePlate,10);
	

	while(answer != 'N')
	{
	cout<<"\n\nEnter service code :";
	cin.getline(serviceCode,5); //When enter loop 2nd time and above, compiler ignored this
	cin.getline(serviceCode,5); //Added another line here

	
	//The rest of the code ( selection ) -process
			
	cout<<"\n+++++++++++++++++++++++++++SPEEDTYRE SERVICE RECEIPT+++++++++++++++++++++";
	cout<<"\nCustomer Name:"<<customerName;
	cout<<"\nVehiclePlate no.:"<<vehiclePlate;
	cout<<"S\nervice Description:"<<serviceDesc;
	TOTprice = TOTprice + earlyPrice;
	cout<<"\nTotal :RM"<<TOTprice;
	cout<<"\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
	cout<<"\n Do you want to make another service?(Y/N):";
	cin>>answer;
	}

}
Last edited on
1
2
char foo;
cin >> foo;

Reads one character from stream. One.

When the user presses keys Shift and 'y', that is one character.
If the user presses Enter too, that is second character. An End-of-line character.

The getline reads up to end of line. That is quick, because the end is there.
 Do you want to make another service?(Y/N):Ya2p4

From that the foo will get the 'Y' and getline reads at least the "a2p4".

One could use ignore to get rid of a newline:
http://www.cplusplus.com/reference/istream/istream/ignore/

or one could check whether the the first newline got something. If not, then read again.
Hello faidi,

I will try to explain what keskiverto is saying.

You need to understand the difference between "cin >>" and "getline(...)".

Note: with "cin >>" or "getline(...)" both will store what you type in an input buffer until you press Enter and then process it into the variable associated with the input.

"cin >>" is known as formatted input which means the variable to the right of ">>" determines what is expected. If "answer" was defined as an "int" it expects a number and anything else will cause "cin" to fail. With "answer" defined as a "char" you can type a letter or a number and it will accept it.

The other part of "cin >>" is that it will extract from the input buffer up to the first white space or new line (\n) whichever comes first leaving whatever is left in the input buffer for the next "cin >>" or "getline" to use. So, the next call to "cin >>" does not wait for keyboard input it just extracts whatever is left in the input buffer. The same is true for "getline". In the end "cin >>" will always leave the "\n" in the input buffer. Not generally a problem for "cin >>", but a problem when followed by a "getline".

"getline", on the other hand, will extract everything up to and including the "\n", but will discard the "\n" leaving the input buffer empty. This is useful when you have input that contains a space or two that you want to keep.

As keskiverto mentioned the use of the "ignore" function will clear the input buffer. In my time here I have seen this used most often:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>. This will produce the largest number available for your computer and compiler based on what is in the header file limits. I tend to put this line after the last "cin >>" or before a "getline" so that the "getline" will work properly. Although I would say it is better to put the "ignore" after the last "cin >>".

This should help:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
while (answer != 'N')
{
	cout << "\n\nEnter service code :";
	cin.getline(serviceCode, 5); //When enter loop 2nd time and above, compiler ignored this
	cin.getline(serviceCode, 5); //Added another line here


	//The rest of the code ( selection ) -process

	cout << "\n+++++++++++++++++++++++++++SPEEDTYRE SERVICE RECEIPT+++++++++++++++++++++";
	cout << "\nCustomer Name:" << customerName;
	cout << "\nVehiclePlate no.:" << vehiclePlate;
	cout << "S\nervice Description:" << serviceDesc;
	TOTprice = TOTprice + earlyPrice;
	cout << "\nTotal :RM" << TOTprice;
	cout << "\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
	cout << "\n Do you want to make another service?(Y/N):";
	cin >> answer;
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
}


As I look over your code I wonder if you are required to use character arrays? A "std::string" would be better. The "std::string" would require the header file "string" not "cstring". Since your program is in C++ I would suggest using the "string" header file and "std::string". Which would change cin.getline(vehiclePlate,10); to std::getline(std::cin, vehiclePlate);. I think you will find using a "std::string" much easier.

Note: Proper indenting helps.

Hope that helps,

Andy
Topic archived. No new replies allowed.