简体   繁体   中英

C++: how to input values separated by comma(,)

int a, b, c, d;

There are 4 variables.

I want user to input 4 values, and each value is separated by comma(,)

Just like this:

stdin:

1,2,3,4

The following code works in C

scanf("%d,%d,%d,%d", &a, &b, &c, &d);

But how should I code in C++?

I'm kind of surprised at the incorrect commentary here [1] .

There are two basic routes you can take:

  • handle the separator with a manipulator-style object, or
  • imbue the stream with a specialized facet that requires whitespace to include a comma.

I will focus on the first; it is typically a bad idea to imbue shared streams with weird behaviors even temporarily (“shared” in the sense that other parts of your code have access to it as well; a local stringstream would be an ideal candidate for imbuing with specialized behaviors).

A 'next item must be a comma' extractor:

#include <cctype>
#include <iostream>

struct extract
{
  char c;
  extract( char c ): c(c) { }
};

std::istream& operator >> ( std::istream& ins, extract e )
{
  // Skip leading whitespace IFF user is not asking to extract a whitespace character
  if (!std::isspace( e.c )) ins >> std::ws;

  // Attempt to get the specific character
  if (ins.peek() == e.c) ins.get();

  // Failure works as always
  else ins.setstate( std::ios::failbit );

  return ins;
}

int main()
{
  int a, b;
  std::cin >> a >> extract(',') >> b;
  if (std::cin)
    std::cout << a << ',' << b << "\n";
  else
    std::cout << "quiznak.\n";
}

Running this code, the extract manipulator/extractor/whatever will succeed only if the next non-whitespace item is a comma. It fails otherwise.

You can easily modify this to make the comma optional:

std::istream& operator >> ( std::istream& ins, optional_extract e )
{
  // Skip leading whitespace IFF user is not asking to extract a whitespace character
  if (!std::isspace( e.c )) ins >> std::ws;

  // Attempt to get the specific character
  if (ins.peek() == e.c) ins.get();

  // There is no failure!
  return ins;
}

...

std::cin >> a >> optional_extract(',') >> b;

Etc.

[1] cin >> a >> b; is not equivalent to scanf( "%d,%d", ...); . C++ does not magically ignore commas. Just as in C, you must treat them explicitly.

The same for the answer using getline() and a stringstream ; while the combination is valid, the actual problem is just shifted from std::cin to another stream object, and still must be treated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM