2

I need to read in a very long Int into a Long Int class I'm making right now and I am overloading the cin >> operator. The user must enter the entire number at once. For example: 444444444444444444444444444

I was planning to use cin.get() and cast the result into an int just so I can grab the first 4 from the stream, but it is NOT working. Can someone please help me with any tips/suggestions?

istream& operator>>(istream &input, LongInt &longint)
{
  int check; ////
  int first;
  first = (int)(cin.get());
  longint.stack_li.push(first);
  cout << first;
  //while (isdigit((int)(input.peek())))
  //{

  //  longint.stack_li.push((int)(check = input.get()));
  //  cout << check;
  //}
  return input;
}

(stack_li is just a stack from a header file I included (Not the STL's) and I made the stack a private variable of the class LongInt belongs to.) When I enter the number 5796 as a long int when my program runs, the output is 55 or 57 or some random 2 digit number, something is clearly wrong. Please let me know!! Thank you very much!!

shauryachats
  • 9,975
  • 4
  • 35
  • 48
  • 1
    By using `cin.get()`, you get only one character, and it is treated as a `char`. Why not get the input as a string, and parse the string to your liking? – Jonny Henly Jan 11 '15 at 06:09
  • Ok, i never thought of that. So you'er saying use get line and store it in a string? Or something similar correct? – Justin Balingit Jan 11 '15 at 06:15
  • Yes, although depending on the size of the number you could use the `long long` type which is 64 bit compared to the 32 bit, `int`, and there are other types for larger integers, take a look at this StackOverflow question. [Types bigger than long long in C++](http://stackoverflow.com/questions/5381882/types-bigger-than-long-long-in-c) I believe C++11 supports the `long long` type as an argument to cin's extraction operator. – Jonny Henly Jan 11 '15 at 06:22
  • This did not work for me. does anyone know how to fix this? string line; getline(cin, line); cout << line; – Justin Balingit Jan 11 '15 at 07:51

1 Answers1

4

When you need to parse your input, you will probably process characters individually. To do so, I would personally use std::istreambuf_iterator<char> although you can also use std::istream::get(). The latter will return an int representing one char or it will return an indication that the end of the stream was reached, i.e., the value std::char_traits<char>::eof(). Using std::istreambuf_iterator<char> you'd just process a sequence like any other to get the same checks, hence my preference. In both cases, you should probably start off skipping whitespace as this is likely to be a separator. Since the input is parsed anyway, the easiest was to do so is to use std::istream::sentry. Putting it all together, you'd have something like this:

std::istream& operator>> (std::istream& in, LongInt& longInt) {
    std::istream::sentry kerberos(in);
    if (kerberos) {
        std::istreambuf_iterator<char> it(in), end;
        if (it == end || !std::isdigit(static_cast<unsigned char>(*it))) {
            std::setstate(std::ios_base::failbit);
        }
        while (it != end && std::isdigit(static_cast<unsigned char>(*it))) {
            // do something with the next digit
        }
    }
    return in;
}
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • Is there something less complex I could use? Not too sure if I can use complex information. Thanks for the answer and effort – Justin Balingit Jan 11 '15 at 07:35
  • @JustinBalingit: Which part of the code you think you don't needed? I think you need all of them (and I had actually forgot handling the case when there is no digit at all which should put the stream into fail stated; now added). – Dietmar Kühl Jan 11 '15 at 15:47