2

In a program, lets say we get a set of integers from the user in the following format:

std::cout << "Enter the new color value as: (red,green,blue)" << std::endl;
string input;
std::cin >> input;

What would then be the most well-practiced way to derive the ints from the string for operation?

Libra
  • 2,544
  • 1
  • 8
  • 24
  • related/dupe: https://stackoverflow.com/questions/28828957/enum-to-string-in-modern-c11-c14-c17-and-future-c20 – NathanOliver Feb 11 '20 at 14:31
  • From what I can tell that only works for enum classes, I'm looking for something that will execute directly on this raw code to give me variables in something like a main method @NathanOliver – Libra Feb 11 '20 at 14:33
  • 1
    One way (with no error checking): `cin >> red; cin.ignore(); cin >> green; cin.ignore(); cin >> blue;` – 001 Feb 11 '20 at 14:40
  • Is there a reason to first put the entire input into a string instead reading the ints directly mixed with some `getchar`? – Albjenow Feb 11 '20 at 14:40
  • @Albjenow No, you could do that, although I am not familiar, could you write an answer with that you're talking about? – Libra Feb 11 '20 at 14:41
  • Given that the performance bound will be in the IO, I'd check the form of the string using `std::regex`, then if I'm happy with that, parse it using good old fashioned `%d`. – Bathsheba Feb 11 '20 at 14:41
  • @JohnnyMopp Could you write an answer with how you'd use that? – Libra Feb 11 '20 at 14:41
  • @Bathsheba I guess I am not looking for what is purely the most efficient, just how this is generally done as I couldn't find anything – Libra Feb 11 '20 at 14:42
  • So the user would have to enter 1,2,3 or (1,2,3)? In the answer, do you want to include the checking of the format? Or is it ok to assume the format is correctly provided? (e.g. 1, 2, 3) – mfnx Feb 11 '20 at 14:48
  • The format will always be correct, following the format "(red,green,blue)" where each is a max of 3 digits and a min of 1 digit @mfnx – Libra Feb 11 '20 at 14:50
  • Why does it need to be the *most efficient*? By waiting for User input, you'll have lost any time gain by using an efficient method to extract numbers from a string. – Thomas Matthews Feb 11 '20 at 14:55
  • Refer to my response to Bathsheba @ThomasMatthews – Libra Feb 11 '20 at 14:58
  • Search the internet for "c++ read CSV". Your input is **C**omma **S**eparated **V**alues. – Thomas Matthews Feb 11 '20 at 15:11
  • @ThomasMatthews I figured, but what about the parentheses? – Libra Feb 11 '20 at 15:11

2 Answers2

2

A simple method is to overload the operator>> in your struct:

struct Pixel
{
  int red;
  int green;
  int blue;
  friend std::istream& operator>>(std::istream& input, Pixel& p);
};

std::istream& operator>>(std::istream& input, Pixel& p)
{
  char c;
  input >> c; // '('
  input >> p.red;
  input >> c; // ','
  input >> p.green;
  input >> c; // ','
  input >> p.blue;
  input >> c; // ')'
  return input;
};

This allows you to do something like this:

Pixel p;
std::cout << "Enter the new color value as: (red,green,blue)" << std::endl;
cin >> p;

You may want to add checks to the input method for correct syntax.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

From the question and comments, I'll assume the starting point is a std::string like:

std::string color { " ( 123, 1, 45 ) " };

The goal is to substract those numbers and convert them into integers. Let's first remove the white spaces:

color.erase(std::remove_if(color.begin(), color.end(), ::isspace), color.end());

We can now extract the numbers as strings:

std::regex reg("\\,");
std::vector<std::string> colors(
    std::sregex_token_iterator(++color.begin(), --color.end(), reg, -1),
    std::sregex_token_iterator()
);

Finally, convert them to integers:

std::vector<int> integers;
std::transform(colors.begin(), colors.end(), std::back_inserter(integers),
           [](const std::string& str) { return std::stoi(str); });
mfnx
  • 2,894
  • 1
  • 12
  • 28