0

I'm a beginner having trouble with a common issue. I'm trying to read standard input line by line in C++ wherein each line is [integer][comma][integer]. For example:

1,1
2,3
12,5

etc. I want to only use the integers in each line and assign them to separate variables. The part of my code that's hassling me looks something like this:

int x,y;
for (string line; getline(cin, line); ) {
   // ...want to have something like
   // x = first integer, y = second integer
   // process x and y
}

So essentially, I don't care about storing the values for the integers on each line, but I do want to process each pair of integers to compare them or whatnot.

I've noticed other solutions that use vectors, stringstream, tokens and/or delimiters, but those were almost always for input lines with multiple delimiters per line - here we only have 1 per line, so I thought there might be a more simple solution.

Thanks for your time and patience.

Klogg
  • 3
  • 2

2 Answers2

2

Try this:

#include <iostream>
#include <sstream>
#include <string>

// ...

for (std::string line; std::getline(std::cin, line); )
{
    std::istringstream iss(line);
    int x, y;
    char c;
    if (!(iss >> x >> c >> y >> std::ws) || iss.get() != EOF || c != ',')
    {
        std::cerr << "Cannot parse line '" << line << "'.\n";
        continue;
    }

    std::cout << "Input: " << x << ", " << y << "\n";
}

(This logic actually allows more lenient input (regarding whitespace) than you give in your example; if you want the matching to be strict, you have to not skip whitespace.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • [Demo](https://ideone.com/buhd65) – Kerrek SB Sep 12 '15 at 14:06
  • Thank you, this worked perfectly! I also noticed how you declared x and y inside the for loop and was going to question it, but it lead me to read up on scope convention (I previously thought it might be faster if the variables are declared once, outside the loop). I'm learning tonnes :) – Klogg Sep 13 '15 at 06:32
0

To read from standard input, you can use the cin command. Read the input as a string and parse it accordingly to get the input.

However, your input here as a predefined format, and we can use that to our advantage by using scanf. Your code will be as follows:

int x,y;
while (scanf("%d,%d",&x,&y) == 1) 
{
  ...
  ...
}

The %d,%d implies that scanf is looking for an input in the form of an integer, followed by a comma, followed by an integer. The scanf(...) == 1 will evaluate to false if the input is not in the format specified, and will help in exiting the while loop if the user presses Enter twice (or gives some other input).

therainmaker
  • 4,253
  • 1
  • 22
  • 41
  • This is an interesting and elegant-looking solution, and it was something like this that I had in mind, although it didn't work for me - when I tried implementing it, it either only read 1 line and finished or it read every line but could only be closed with Ctrl+C (although it's almost definitely because I did something wrong in my implementations). Thank you! – Klogg Sep 13 '15 at 06:42
  • @Klogg : Glad you like it. There is a possibility that I may have done a mistake as well, because I haven't verified this code, and haven't used much of scanf. Maybe the termination of the while loop is incorrect on my part. A bit of search online regarding scanf should get you the right answer though. – therainmaker Sep 13 '15 at 08:31