Using ifstream as fscanf

后端 未结 2 2102
萌比男神i
萌比男神i 2021-02-20 16:56

Assume that I have an input as follows:

N (X_1,Y_1) (X_2,Y_2) .... (X_N, Y_N)

where N, X_i and Y_i are integers.

An example:

         


        
相关标签:
2条回答
  • 2021-02-20 17:25
    cin >> N;
    for (int i = 0; i < N; i++)
    {
        cin.ignore(100,'(');
        cin >> X[i];
        cin.ignore(100,',');
        cin >> Y[i];
        cin.ignore(100,')');
    }
    

    It can handle whitespaces also, as it can read input like:

    2  (  1  ,  3  )    (  5  ,  6  )
    

    Demonstration at ideone: http://www.ideone.com/hO0xG

    0 讨论(0)
  • 2021-02-20 17:28
    int n, x, y;
    char c;
    if (is >> n)
        for (int i = 0; i < n; ++i)
            if (is >> c && c == '(' &&
                is >> x &&
                is >> c && c == ',' &&
                is >> y &&
                is >> c && c == ')')
            {
                X[i] = x;
                Y[i] = y;
            }
            else
                throw std::runtime_error("invalid inputs");
    

    You can simplify the all-important inner if condition above to...

    is >> chlit('(') >> x >> chlit(',') >> y >> chlit(')')
    

    ...with a simple support type for consuming a specific character:

    struct chlit
    {
        chlit(char c) : c_(c) { }
        char c_;
    };
    
    inline std::istream& operator>>(std::istream& is, chlit x)
    {
        char c;
        if (is >> c && c != x.c_)
            is.setstate(std::iostream::failbit);
        return is;
    }
    

    See a complete program illustrating this on ideone here.

    An old post of mine did something similar for consuming specific strings. (The above chlit could be a template, but chlit<','>() is ugly to read and write - I'd rather trust the compiler).

    0 讨论(0)
提交回复
热议问题