0

How would one go about overloading the cin >> operator in c++ to input a fraction of unknown size/chars? Specifically, the person can enter 1/2 or 12/4 or 1/100 and it has to be able to accept any of them and input them into a numerator and denominator in a fraction object. Is there a simply command to determine where a character is in a string and then do something different with the characters before and after it?

And I can't have the person hit return/enter after inputting the numerator and denominator slash. Such as 4 (enter) / (enter) 15 (enter). They must be entered in one line and manipulated from there.

Note: I did already look at the similar questions on this site, but none seemed to address fractions which weren't composed of a single int numerator and denominator.

Neko
  • 51
  • 1
  • 1
  • 9
  • possible duplicate of [How to split a string in C++?](http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c) – Jack Feb 11 '14 at 04:01
  • I don't think so. Because I need to tell the computer how to find the slash before it is told where to split it. And it's the first part I can't figure out. – Neko Feb 11 '14 at 04:07

4 Answers4

2

here is a very simple example of extraction using istringstream

note that, you must not put spaces when reading; eg : 123 / 34 if you want that instead, just use : std::cin >> numerator >> dummy_char >> denominator;

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

int main()
{
    std::string str( "123/455" );
    std::istringstream is( str );
    std::size_t i, j = 0;

    if( !(is >> i) ) return 1; // extract

    is.get(); // get the '/'

    if( !(is >> j) ) return 1; // extract

    std::cout << i << '/' << j;
}
1

Just use cin to read an int, the slash, and another int.

int num, den;
string slash;

cin >> num >> slash >> den;

// optionally check that slash contains a slash if you don't trust the user
// if("/" != slash) abort();

EDIT: I just tried this, and it only works if there is a space after the slash before the denominator. If there are no spaces, you can change slash to a char.

EDIT2: If you had a Fraction struct such as the following,

struct Fraction
{
    int num, den;
};

then you can overload operator >> to read in the fraction directly.

istream& operator>>(istream &in, Fraction &f)
{
    string slash;
    return in >> f.num >> slash >> f.den;
}

// in main or somewhere
Fraction f;
cin >> f;

As before, you can change slash to char if there will be no spaces, and you may want to do some error checking before returning the in object from operator>>.

Nicu Stiurca
  • 8,747
  • 8
  • 40
  • 48
  • But could I use this format to overload the >> operator? It seems to me like this wouldn't work for that purpose. While it's probably blindingly obvious to everyone else, I don't suppose you could give me a hint? – Neko Feb 11 '14 at 05:01
  • @Neko It sounds like you first need to define a Fraction class, and then yeah overloading is easy. I'll make another edit. – Nicu Stiurca Feb 11 '14 at 05:16
  • Thanks very much! That makes a lot more sense. – Neko Feb 11 '14 at 17:16
0
  1. load the whole thing as a string,
  2. use string.find() to find the /,
  3. Split the string like noted in Split a string in C++?, and convert the parts to numbers using ether stringstream, atoi() or anything else,
  4. ???
  5. Profit.

(sorry for 4 and 5, couldn't resist myself)

Note: Of course you should do that inside an overloaded operator>> of your fraction class.

Community
  • 1
  • 1
Paweł Stawarz
  • 3,952
  • 2
  • 17
  • 26
0

You want to read and match a / character between the numerator and denominator, so you need the missing operator>>(istream&, char) function:

std::istream &operator>>(std::istream &in, char ch) {
    while (std::isspace(in.peek())) in.get();
    if (in.peek() == ch)
        in.get();
    else
        in.setstate(std::ios_base::failbit);
    return in;
}

std::istream &operator>>(std::istream &in, fraction &fr) {
    in >> fr.num >> '/' >> fr.denom;
    return in;
}

That function (or something like it) really should be part of the standard library, but its easy enough to add it yourself.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226