Reputation: 11
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++?
Upvotes: 0
Views: 7359
Reputation: 10028
I’m kind of surprised at the incorrect commentary here[1].
There are two basic routes you can take:
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.
Upvotes: 2