If bad command, skip rest of line

Hey all,

I was wondering, what is the easiest way to ignore the rest of an input line if there is bad input from the first word in a string. Essentially I read a command in from cin, and if it's a bad command I want to skip the rest of the line. For example:

insrt something

so it reads in insrt as a command, realizes it's a bad command, prints an error message, and then I want it to skip the rest of the line (the "something" essentially)

The problem I'm having is if the bad command is something like:

yikes that's bad

It prints the proper error message, and if I enter another command, it will work. But if the command is something like:

yikes

Then the next command I enter is not read in

This is what I was trying within a while loop that reads while(cin >> command):

1
2
3
4
5
6
7
8
9
10
11
		else{
			cerr << "Illegal command <" << command << ">." << endl;
			if(!isspace(cin.peek())){
				getline(cin, command);
			}
			else{
				cin.ignore();
			}

			
		}
Last edited on
I assume you have an chain of if-else statements above the else part that you have posted. I don't see any prblem with it. It doesn't work?
It doesn't. It works if I have an invalid command with parameters, but if it is just an invalid command without parameters, the following command doesn't seem to be read in to the command variable

Here's the full line of 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
	while(cin >> command){
		cin.ignore();

		if(command == "echo"){
			getline(cin, input);
			cout << input << endl;

		}
		else if(command == "insert"){
			getline(cin, input);
			tree.insert(input);
		}

		else if(command == "print"){
			tree.print();
		}
		else if(command == "find"){
			getline(cin, input);
			tree.find(input);
		}
		else if(command == "size"){
			cout << tree.size() << endl;
		}
		else if(command == "breadth"){
			tree.breadth();
		}
		else if(command == "distance"){
			cout << "Average distance of nodes to root = " << tree.distance() << endl;
		}
		else{
			cerr << "Illegal command <" << command << ">." << endl;
			if(!isspace(cin.peek())){
				getline(cin, command);
			}
		}
	}
Last edited on
If the line ends directly after the command then cin.ignore(); on line 2 will discard the newline character. getline just search for the next newline character it can find but because you have already removed the newline character it will read the line that follows (and wait if it has not been entered yet).
I solved this by putting the cin.ignore() on line 2 within this:

1
2
3
		if(isspace(cin.peek())){
			cin.ignore();
		}


I'm still getting the same problem though. The issue I seem to be running into is that if it's a newline, cin.peek() checks the next line, which for both cases will return isspace(cin.peek()) to return false

I essentially think I need to revise this to something like:

1
2
3
4
5
6
7
                       if(there was a newline character){
                          //do nothing
                        {

                        else if(!isspace(cin.peek())){
				getline(cin, command);
			}


I'm not entirely sure how to check for this though...
Last edited on
Alright so I figured out a way to do it, if you know of a better way though feel free to let me know. Essentially I made a bool variable called oneCommand that is set to true if there is a '\n' char returned from cin.peek() like so:


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
	while(cin >> command){
		if(cin.peek() == '\n'){
		    oneCommand = true;
		}
		else if(isspace(cin.peek())){
			cin.ignore();
		}

		if(command == "echo"){
			getline(cin, input);
			cout << input << endl;

		}
		else if(command == "insert"){
			getline(cin, input);
			tree.insert(input);
		}

		else if(command == "print"){
			tree.print();
		}
		else if(command == "find"){
			getline(cin, input);
			tree.find(input);
		}
		else if(command == "size"){
			cout << tree.size() << endl;
		}
		else if(command == "breadth"){
			tree.breadth();
		}
		else if(command == "distance"){
			cout << "Average distance of nodes to root = " << tree.distance() << endl;
		}
		else{
			cerr << "Illegal command <" << command << ">." << endl;
			if(oneCommand == true){

			}
			else if(!isspace(cin.peek())){
				getline(cin, input);
			}
			


			
		}
		oneCommand = false;
	}


Thank you for your help! It's always so much easier working through problems with other people
xD
Cheers
Since your input is in a series of lines and each line stands alone, I would be inclined to use a combination of getline and stringstream:
1
2
3
4
5
6
7
8
9
  string line;
  while (getline(cin, line))
  { // Have a full line
     stringstrem ss (line);  // create a stream from the line just read
     ss >> command;
     //  Parse additional tokens from ss as required
     //  If at some point I don't like the command, I can just continue with the next iteration of the loop.  
    //  cin is alreay pointing to the next line.
  }
Topic archived. No new replies allowed.