Hi All,
I am new to C++. I am practicing loops and i need some help. This one behaves strangely. What i want is for this loop to accept numbers from 1 to 4 for options (strictly numbers) and no other characters. When executed and run, if the input is letters or characters, it clears, dumps the wrong input to a string and loops again asking to enter the right data. But then if i enter the right data (numbers from 1-4), it goes nuts. Does not accept the right number when typed for the first number. I have to enter it again.

Can someone pls explain to me the reason for this and help me correct the code. Thanks.

#include <iostream>
#include <string>		
#include <cstdlib>		// for system 

using namespace std;

int main()
{

int dept_code = 0;
string wrongSelection;

cout << "\nChoose a Department to Proceed. Enter Dept. No. (1,2, 3 or 4)\n";

do
    {
    cout << "\nDepartments\n-----------\n1) Accounting Dept." << "\n2) Purchasing Dept." << "\n3) Marketing Dept." << "\n4) Technical Dept.\n\n";
    cin >> dept_code;
    
    if(!(cin >> dept_code)) 
    if ((dept_code <1) || (dept_code >4))
    {
      cin.clear();
      cin >> wrongSelection; // dump to string
      
      system("clear"); // for Linux / Unix 
      // system("CLS"); // for Win
      
      cout << "\nInvalid selection! Choose one of the departments between 1 & 4\n";
      cout << "\nDepartments\n-----------\n1) Accounting Dept." << "\n2) Purchasing Dept." << "\n3) Marketing Dept." << "\n4) Technical Dept.\n\n";
      cin >> dept_code;}
    }
      while ((dept_code <1) || (dept_code >4));

if (dept_code == 1)
{ cout << "\nYou have chosen Accounting Dept."; }
else if (dept_code == 2)
{ cout << "\nYou have chosen Purchasing Dept."; }
else if (dept_code == 3)
{ cout << "\nYou have chosen Marketing Dept."; }
else if (dept_code == 4)
{ cout << "\nYou have chosen Technical Dept."; }

}

well you almost have it..but some lines there are not neede...

#include <iostream>
#include <string>		
#include <cstdlib>		// for system 

using namespace std;

int main()
{

int dept_code = 0;
string wrongSelection;

cout << "\nChoose a Department to Proceed. Enter Dept. No. (1,2, 3 or 4)\n";

do
    {
		system("CLS");
    cout << "\nDepartments\n-----------\n1) Accounting Dept." << "\n2) Purchasing Dept." << "\n3) Marketing Dept." << "\n4) Technical Dept.\n\n";
    cin >> dept_code;
    
   

    }      while ((dept_code <1) || (dept_code >4));

if (dept_code == 1)
{ cout << "\nYou have chosen Accounting Dept."; }
else if (dept_code == 2)
{ cout << "\nYou have chosen Purchasing Dept."; }
else if (dept_code == 3)
{ cout << "\nYou have chosen Marketing Dept."; }
else if (dept_code == 4)
{ cout << "\nYou have chosen Technical Dept."; }

}

your code :)..edited a little

Thank you Mr. Anyzen for your help. I just compiled and ran it in my system and i have this observation. I enter the numbers and it works perfect. But the problem is if i enter any other characters other than 1-4. The program hangs and i have to kill using Ctrl+C.
What i basically want here is for this loop to ignore everything typed (letters, signs, and any other numbers )other than 1-4.

well you almost have it..but some lines there are not neede...

#include <iostream>
#include <string>		
#include <cstdlib>		// for system 

using namespace std;

int main()
{

int dept_code = 0;
string wrongSelection;

cout << "\nChoose a Department to Proceed. Enter Dept. No. (1,2, 3 or 4)\n";

do
    {
		system("CLS");
    cout << "\nDepartments\n-----------\n1) Accounting Dept." << "\n2) Purchasing Dept." << "\n3) Marketing Dept." << "\n4) Technical Dept.\n\n";
    cin >> dept_code;
    
   

    }      while ((dept_code <1) || (dept_code >4));

if (dept_code == 1)
{ cout << "\nYou have chosen Accounting Dept."; }
else if (dept_code == 2)
{ cout << "\nYou have chosen Purchasing Dept."; }
else if (dept_code == 3)
{ cout << "\nYou have chosen Marketing Dept."; }
else if (dept_code == 4)
{ cout << "\nYou have chosen Technical Dept."; }

}

your code :)..edited a little

If the user wrongly typed some other character / string or some other number (other than 1-4), i want the user to be notified of the wrong selection and present him with the same options again. Thats the easy part. But then clearing the screen and looping back in case of wrong characters and numbers was different in my first code. i needed help there. Pls test the originally posted code by entering wrong options (letters / numbers) and u will understand what i am trying to say. Any help on that will be most welcome. Thank you

well you almost have it..but some lines there are not neede...

#include <iostream>
#include <string>		
#include <cstdlib>		// for system 

using namespace std;

int main()
{

int dept_code = 0;
string wrongSelection;

cout << "\nChoose a Department to Proceed. Enter Dept. No. (1,2, 3 or 4)\n";

do
    {
		system("CLS");
    cout << "\nDepartments\n-----------\n1) Accounting Dept." << "\n2) Purchasing Dept." << "\n3) Marketing Dept." << "\n4) Technical Dept.\n\n";
    cin >> dept_code;
    
   

    }      while ((dept_code <1) || (dept_code >4));

if (dept_code == 1)
{ cout << "\nYou have chosen Accounting Dept."; }
else if (dept_code == 2)
{ cout << "\nYou have chosen Purchasing Dept."; }
else if (dept_code == 3)
{ cout << "\nYou have chosen Marketing Dept."; }
else if (dept_code == 4)
{ cout << "\nYou have chosen Technical Dept."; }

}

your code :)..edited a little

I will assume here that the issue is that if cin>>intVar encounters an incorrect input it goes into a fail state. This will not correct itself. I suggest reading a character variable as this is what you want, then use the old c function isdigit() to check if the input is a number or not. short code snippet below of this.

char userIn;
bool done = false;
while(!done)//loop untill we get a correct input
{
   //display options blah blah....
   cin>>userIn;
   if(isdigit(userIn))
   {
     //We have the input we want
     done = true;
   }
   else
   {
     //display wrong input message
   }
   //may want to use a cin.ignore here or one of narue's functions  to ensure stability
}

//convert from char to int (not really neccessary unless you want an int)
//int var = atoi(userIn);
int var = userIn-'0'; //deletes the offset from the character '0' 
                      //so if user inputted '1' remove '0' = (int) 1

This should solve your problem

Edited 6 Years Ago by Kanoisa: n/a

Thank you Kanoisa for your help. I will try your method and post back.

I will assume here that the issue is that if cin>>intVar encounters an incorrect input it goes into a fail state. This will not correct itself. I suggest reading a character variable as this is what you want, then use the old c function isdigit() to check if the input is a number or not. short code snippet below of this.

char userIn;
bool done = false;
while(!done)//loop untill we get a correct input
{
   //display options blah blah....
   cin>>userIn;
   if(isdigit(userIn))
   {
     //We have the input we want
     done = true;
   }
   else
   {
     //display wrong input message
   }
   //may want to use a cin.ignore here or one of narue's functions  to ensure stability
}

//convert from char to int (not really neccessary unless you want an int)
//int var = atoi(userIn);
int var = userIn-'0'; //deletes the offset from the character '0' 
                      //so if user inputted '1' remove '0' = (int) 1

This should solve your problem

Kanoisa, can u pls elaborate your method in detail with actual code from my first post. Also what are Narue's functions?

I will assume here that the issue is that if cin>>intVar encounters an incorrect input it goes into a fail state. This will not correct itself. I suggest reading a character variable as this is what you want, then use the old c function isdigit() to check if the input is a number or not. short code snippet below of this.

char userIn;
bool done = false;
while(!done)//loop untill we get a correct input
{
   //display options blah blah....
   cin>>userIn;
   if(isdigit(userIn))
   {
     //We have the input we want
     done = true;
   }
   else
   {
     //display wrong input message
   }
   //may want to use a cin.ignore here or one of narue's functions  to ensure stability
}

//convert from char to int (not really neccessary unless you want an int)
//int var = atoi(userIn);
int var = userIn-'0'; //deletes the offset from the character '0' 
                      //so if user inputted '1' remove '0' = (int) 1

This should solve your problem

Narue's functions? I don't see where she posted in this thread. Or are you referring to this thread? If so, that method is an advanced method of manipulating the input stream to be sure that it is always clean. It makes heavy use of the member function istream::ignore() to remove extra/lingering characters from the input stream. If you look closely, you'll also see that she uses the function ios::clear() to clear any error flags.

Another function that you may want to look at is ios::good().

Basic idea of how this would work (with minor thievery from Narue):

int userChoice = 0;
const int IGNORE_COUNT = std::numeric_limits<std::streamsize>::max();

do {
  cout << "Enter your choice: ";
  cin >> userChoice;

  if (!cin.good()) {  //if input stream is corrupt due to invalid input
    cin.clear();
    cin.ignore(IGNORE_COUNT, '\n');
  }

} while (userChoice < 1 || userChoice > 4)

Edited 6 Years Ago by Fbody: n/a

Thank you Fbody for your reply. The Narue's function mention was made in comments in line 16 of code Kanoisa mentioned. I think i am getting too far. I still need to learn a lot lot many new things before questioning about advanced features.

Narue's functions? I don't see where she posted in this thread. Or are you referring to this thread? If so, that method is an advanced method of manipulating the input stream to be sure that it is always clean. It makes heavy use of the member function istream::ignore() to remove extra/lingering characters from the input stream. If you look closely, you'll also see that she uses the function ios::clear() to clear any error flags.

Another function that you may want to look at is ios::good().

Basic idea of how this would work (with minor thievery from Narue):

int userChoice = 0;
const int IGNORE_COUNT = std::numeric_limits<std::streamsize>::max();

do {
  cout << "Enter your choice: ";
  cin >> userChoice;

  if (!cin.good()) {  //if input stream is corrupt due to invalid input
    cin.clear();
    cin.ignore(IGNORE_COUNT, '\n');
  }

} while (userChoice < 1 || userChoice > 4)

The Narue's function mention was made in comments in line 16 of code Kanoisa mentioned.

Oh, I see it now... Kaniosa is probably referring to this thread.

Edited 6 Years Ago by Fbody: n/a

Sir, i am getting error on this line of your code.

const int IGNORE_COUNT = std::numeric_limits < std::streamsize>::max();

it says 'numeric_limits's is not a member of 'std'.

Narue's functions? I don't see where she posted in this thread. Or are you referring to this thread? If so, that method is an advanced method of manipulating the input stream to be sure that it is always clean. It makes heavy use of the member function istream::ignore() to remove extra/lingering characters from the input stream. If you look closely, you'll also see that she uses the function ios::clear() to clear any error flags.

Another function that you may want to look at is ios::good().

Basic idea of how this would work (with minor thievery from Narue):

int userChoice = 0;
const int IGNORE_COUNT = std::numeric_limits<std::streamsize>::max();

do {
  cout << "Enter your choice: ";
  cin >> userChoice;

  if (!cin.good()) {  //if input stream is corrupt due to invalid input
    cin.clear();
    cin.ignore(IGNORE_COUNT, '\n');
  }

} while (userChoice < 1 || userChoice > 4)

Be cautious about cut/pasting directly from the forum to your code. That code was just an example and may or may not be compatible with the rest of your code. It was deliberately written in a way to increase the likelihood that it is not compatible for this reason. That way you have to think about it a little more to make it work.

All that line is doing is declaring a constant to avoid using a "magic number" in the ignore() function.

You have to include the <limits> header to access the information used on the right side of the declaration.

Really though, an arbitrarily large value will work. A common one is 80.

const int IGNORE_COUNT = 80;

Edited 6 Years Ago by Fbody: n/a

It worked. Thank you.

One final question not related to this. How many years will it take one on avg to master C++ (doing self study) or atleast get a fair touch of this lang? :)

All that line is doing is declaring a constant to avoid using a "magic number" in the ignore() function.

You have to include the <limits> header to access the information used on the right side of the declaration.

Really though, an arbitrarily large value will work. A common one is 80.

const int IGNORE_COUNT = 80;

I'm afraid there's really not an answer to that question, or at least I don't have one. IMO, it's going to depend on your dedication, your ability to grasp various concepts, and the field you plan to get into. You can be a "master" game programmer without being an expert in embeded systems or robotics. It's a relative term that is a matter of specialization.

I've been messing around with C++ in general for about a year now. I've had 2 college courses and read several books. Before that, I messed around with PHP and FreeBASIC for about 2-years. But I'm nowhere close to a "master" of any of them. There's way too much I don't know yet.

Edited 6 Years Ago by Fbody: n/a

Sir, I just wanted to try your code and see if it works. So i copy/pasted it to a new file, compiled and got that error. Now i know that it works, I will do the post-mortem of that part and study it in detail. Thanks

Be cautious about cut/pasting directly from the forum to your code. That code was just an example and may or may not be compatible with the rest of your code. It was deliberately written in a way to increase the likelihood that it is not compatible for this reason. That way you have to think about it a little more to make it work.

All that line is doing is declaring a constant to avoid using a "magic number" in the ignore() function.

You have to include the <limits> header to access the information used on the right side of the declaration.

Really though, an arbitrarily large value will work. A common one is 80.

const int IGNORE_COUNT = 80;

I'm not sure why you're calling me "sir" (which is accurate), but it's really not necessary.

That was just a friendly warning because I may have mis-read your wording in a previous post.

As long as you understand what has been posted and can apply the concept(s) behind it, whatever you do with code snippets is fine. Just be aware that simply because a piece of code is posted doesn't mean it's directly compatible with yours.

Edited 6 Years Ago by Fbody: n/a

>How many years will it take one on avg to master C++ (doing self study) or atleast get a fair touch of this lang?
Mastery is quite different from competence (which is how I interpret "a fair touch"). If you're an experienced programmer you can become competent with C++ in less than a year. Proficiency suggests experience, and experience only comes from writing lots of code, reading lots of code, and studying the literature. So to become truly proficient in C++ I'd say 5+ years unless you have no life. ;)

As for mastery, I'd say it's impossible. C++ is an extremely robust language with not a few nuances, and it's constantly evolving both in the language proper and ways of using it. I think of mastery as knowing and having experience with everything there is to know.

Comments
Agreed :)

I fully agree with what you said. :)

>How many years will it take one on avg to master C++ (doing self study) or atleast get a fair touch of this lang?
Mastery is quite different from competence (which is how I interpret "a fair touch"). If you're an experienced programmer you can become competent with C++ in less than a year. Proficiency suggests experience, and experience only comes from writing lots of code, reading lots of code, and studying the literature. So to become truly proficient in C++ I'd say 5+ years unless you have no life. ;)

As for mastery, I'd say it's impossible. C++ is an extremely robust language with not a few nuances, and it's constantly evolving both in the language proper and ways of using it. I think of mastery as knowing and having experience with everything there is to know.

I am new comers for C++
i have same trouble like that.
So thank you for all comments.

SNIP

Edited 6 Years Ago by happygeek: fake sig snipped

This question has already been answered. Start a new discussion instead.