使用cin以特定格式阅读

Reading in a specific format with cin

本文关键字:格式 定格 cin 使用      更新时间:2023-10-16

如何使用cin以特定格式读取?示例:-为了读取复数,我希望用户像往常一样输入:x+yi,所以我想要这样的东西:cin>>x>>"+">>y>>"i";但这是一个错误。什么是正确的方法?非常感谢您的帮助。

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

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

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

根据我对一个模糊相关问题的回答,使用流解析通常是个坏主意,但可以做到:

我写了一些可以读取字符串和字符文字的代码。与正常的流读取一样,如果它获得无效数据,它会设置流的坏比特。这应该适用于所有类型的流,包括宽流。将以下四个功能粘贴在标题中:

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

概念验证。现在,您可以cin字符串和字符文字,如果输入不完全匹配,它的行为就像任何其他未能正确输入的类型一样。请注意,这只匹配不是第一个字符的字符串文字中的空白。它只有三个功能,所有这些功能都非常简单。

最好只使用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
       }
   }
}

请注意,此操作可能会失败。