How do I specify more than one delimiter for cin.ignore() in C++?

Viewed 452

The following is my code:

// Program to print the initials of a name
#include <iostream>
using namespace std;

int main() {
  char first, last;
  cout<<"Enter first and last name: ";
  first = cin.get();
  cin.ignore(10000,' ');
  last = cin.get();
  cout<<first<<" "<<last;
  return 0;
}

I was looking for a way to specify more than one delimiter as the second parameter of cin.ignore(), e.g. cin.ignore(10000,'\n' or ' '). Is there a way to achieve this?

2 Answers

The simplest way to do this is just to peek() the next character, check if it's in the list of delimiters, and if not then ignore it:

while (std::cin.peek() != '\n' && std::cin.peek() != ' ' && !std::cin.eof())
    std::cin.ignore(1);

Or:

char delim[] = { ' ', '\n' };
int delim_len = sizeof(delim) / sizeof(char);
while( std::find(delim, delim+delim_len, std::cin.peek()) == delim+delim_len) && !std::cin.eof() )
    std::cin.ignore(1);

From cplusplus.com:

int peek();

Peek next character.

Returns the next character in the input sequence, without extracting it: The character is left as the next character to be extracted from the stream.

If any internal state flags is already set before the call or is set during the call, the function returns the end-of-file value (EOF).

Note: from the std::istream::ignore reference, also on cplusplus.com, we can see that only providing one parameter sets the ignore() delimiter to EOF by default:

istream& ignore (streamsize n = 1, int delim = EOF);

You could use std::any_of to read until the read character is any of a set of characters that you define yourself.

Example:

#include <algorithm> // any_of
#include <iterator>  // istreambuf_iterator
#include <string>

std::istream& myignore(std::istream& is, const std::string& delims) {
    if(std::any_of(std::istreambuf_iterator<char>(is),
                   std::istreambuf_iterator<char>{},
                   [&delims](char ch){
                       return delims.find(ch) != std::string::npos;
                   }
    )) is.get(); // read the delimiter to remove it
    return is;
}

Then instead of calling cin.ignore(10000, ' '), you call myignore(cin, " \n");

Related