2013-02-15 113 views
1

如何用cin读取特定格式? 例如: - 为了读取一个复数,我希望用户像往常一样输入它:x + yi, 所以我想要这样的: c >> >> >> >> >> >> >> >> “; 但是这是一个错误。什么是正确的方式?非常感谢。用cin读取特定格式

+0

考虑使用'scanf',它可能是读取格式化数据的更好选择。 – andre 2013-02-15 19:17:48

+0

阅读直到换行,然后在内部解析。 – 2013-02-15 19:19:24

+0

实际上我用它来重载输入分辨率运算符,这就是为什么我需要cin – aceBox 2013-02-15 19:20:13

回答

1

一个非常简单的解决方案:

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

在 “现实生活” 的代码你建立/使用class complex,和过载操作>>.

我尝试在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

标准输入:1E4L1e3g - >标准输出:Error: x=10000, plus=L, y=1000, img=g

标准输入:a+3i - >标准输出:Error: x=0, plus=, y=0, img=

标准输入:1e3+93E-2i - >标准输出:Complex: 1000+0.93i

+0

'1E4L1e3g'将是一个适当的复数做法。 – 2013-02-15 19:20:16

+0

此解决方案在读取'x'失败时不处理该情况,例如读取一个字母而不是数字。 – 2013-02-15 19:30:22

+0

@BartekBanachewicz我无法理解你的意思。 '1E4L1e3g'出现错误。 – qPCR4vir 2016-05-12 15:29:11

1

这将是一定要好只使用std::complex

这里是说明我的意见伪代码:

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 
     } 
    } 
} 

注意,该操作可能会失败。

2

按照my answer on a vaguely related question,与流解析通常是一个坏主意,但可以做到:

我编写了一段代码,可以在字符串和字符阅读。与普通的流读取一样,如果它获取无效数据,它将设置流的坏点。这应该适用于所有类型的流,包括宽流。在头坚持这四个功能:

#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); 
} 

,它将使输入字符很容易:

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

PROOF OF CONCEPT。现在,您可以使用cin字符串和字符文字,并且如果输入不完全匹配,则它的行为与任何其他无法正确输入的类型相同。请注意,这只能匹配不是第一个字符的字符串中的空格。它只有三个功能,所有这些功能都很简单。