aceBox
aceBox

Reputation: 731

Reading in a specific format with cin

How can i read in a specific format using cin? Example:-for reading a complex number, I would like the user to enter it as usual:x+yi, so i want something like this: cin>>x>>"+">>y>>"i"; But this is giving an error.What is the right way?Help greatly appreciated.

Upvotes: 2

Views: 13245

Answers (3)

qPCR4vir
qPCR4vir

Reputation: 3571

A very simple solution:

char plus,img;
double x,y;
cin>> x >> plus >> y >> img;
if (plus!='+' || img!='i')     ...error

In "real life" code you build/use a class complex, and overload the operator >>.

I try it in Ideone: http://ideone.com/ZhSprF

#include <iostream>
using namespace std;

int main() 
{
    char plus{},img{};
    double x{},y{};
    cin>> x >> plus >> y >> img;
    if (plus!='+' || img!='i') 
        cout << "\nError: "<< "x=" << x <<", plus="  << plus <<", y="  << y <<", img="  << img;
    else
        cout << "\nComplex: " << x << plus << y << img;


    return 0;
}

stdin: 3 + 4i --> stdout: Complex: 3+4i

stdin: 1E4L1e3g --> stdout: Error: x=10000, plus=L, y=1000, img=g

stdin: a+3i --> stdout: Error: x=0, plus=, y=0, img=

stdin: 1e3+93E-2i --> stdout: Complex: 1000+0.93i

Upvotes: 2

Mooing Duck
Mooing Duck

Reputation: 66922

As per my answer on a vaguely related question, parsing with streams is usually a bad idea, but can be done:

I wrote a bit of code that can read in string and character literals. Like normal stream reads, if it gets invalid data it sets the badbit of the stream. This should work for all types of streams, including wide streams. Stick these four functions in a header:

#include <iostream>
#include <string>
#include <array>
#include <cstring>

template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&literal)[N]) {
        std::array<e, N-1> buffer; //get buffer
        in >> buffer[0]; //skips whitespace
        if (N>2)
                in.read(&buffer[1], N-2); //read the rest
        if (strncmp(&buffer[0], literal, N-1)) //if it failed
                in.setstate(in.rdstate() | std::ios::badbit); //set the state
        return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& literal) {
        e buffer;  //get buffer
        in >> buffer; //read data
        if (buffer != literal) //if it failed
                in.setstate(in.rdstate() | std::ios::badbit); //set the state
        return in;
}
//redirect mutable char arrays to their normal function
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
        return std::operator>>(in, carray);
}

And it will make input characters very easy:

if (cin>>x>>"+">>y>>"i";)  {
    // read correctly
}

PROOF OF CONCEPT. Now you can cin string and character literals, and if the input is not an exact match, it acts just like any other type that failed to input correctly. Note that this only matches whitespace in string literals that aren't the first character. It's only three functions, all of which are brain-dead simple.

Upvotes: 2

Bartek Banachewicz
Bartek Banachewicz

Reputation: 39370

It would be certainly better to just use std::complex.

Here's a pseudocode illustrating my comments:

struct Complex { double real, imag; }

istream& operator>> (Complex& c, istream& str)
{
   // read until whitespace
   char C;
   string Buffer;

   enum { READING_REAL, READING_PLUS, READING_IMAG }
   State = READING_REAL;


   C = str.peek();
   while (/* C is not whitespace */)
   {
       // actually read C
       switch(State) {
       case READ_REAL:
           // check if it fits allowed double syntax
           // continue until first double is read
           /* when it is
               c.real = parsedouble(Buffer);
               Buffer.clear();
               State = READ_PLUS;
           */
       case READ_PLUS:
           // accept plus sign
       case READ_IMAG:
           // read 2nd double
       }
   }
}

Note that this operation can fail.

Upvotes: 1

Related Questions