10

次のような入力があるとします。

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

ここで、N、X_i、および Y_i は整数です。

例:

2 (55,1) (521,7)

これを読むには、次のようなことができます (すべての変数が定義されていると仮定します):

fscanf(fin,"%d ",&N);
for (int i = 0; i < N; i++)
   fscanf(fin,"(%d,%d) ", &X[i], &Y[i]);

問題は、ifstream を使用してこれを簡単に行うにはどうすればよいかということです。文字列を取得でき、次に数字以外を取り除くことができ、stringstream を使用して 2 つの数値を取得できますが、これは少し面倒に思えます。もっと簡単でエレガントな方法はありますか?

ありがとう

4

2 に答える 2

7
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");

上記の最も重要な内部条件を単純化しifて...

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

...特定の文字を消費するための単純なサポートタイプ:

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

ここでideoneでこれを説明する完全なプログラムを参照してください。

私の古い投稿は、特定の文字列を消費するために同様のことをしました。(上記chlitはテンプレートである可能性がありますが、chlit<','>()読み取りと書き込みは醜いです-私はむしろコンパイラを信頼したいと思います)。

于 2011-01-17T08:38:38.733 に答える
3
cin >> N;
for (int i = 0; i < N; i++)
{
    cin.ignore(100,'(');
    cin >> X[i];
    cin.ignore(100,',');
    cin >> Y[i];
    cin.ignore(100,')');
}

次のような入力を読み取ることができるため、空白も処理できます。

2  (  1  ,  3  )    (  5  ,  6  )

ideone でのデモンストレーション: http://www.ideone.com/hO0xG

于 2011-01-17T09:29:39.790 に答える