3

私はそのstoiような関数を持っています:

static int *stoi(const char *c) {
    int *r = new int[2];
    r[1] = sscanf(c, "%d", &r[0]);
    return r;
}

c = "a5"たとえば、私が与えるとき、それは機能しません。

私が与えるときc = "543336535"、それは働きます。

しかし、私が与えるc = "45sdfff-sdbsdf esg5sq4f"とそれは返されますr[0] = 45、そして私はそれを望んでいません。なぜなら45...の後にいくつかの数字以外の文字があるからです。

関数に数値のみの文字列を読み取らせたいだけです。

4

2 に答える 2

5

%n既存のコードに最小限の変更を加えるには、次の機能を使用できますsscanf

int chars_read;
r[1] = sscanf(c, "%d%n", &r[0], &chars_read);

chars_readが文字列の長さより短い場合、すべてsscanfの文字が消費されていないため、文字列は単一の整数だけで構成されていません。

の Linux ドキュメントは、 scanfTechnical Corrigendum 1で導入された追加の例が標準と矛盾していることを指摘していますが、それまでの間、標準は矛盾を解決するために更新されました。sscanf遭遇する可能性のある実装の不確実な動作に直面して、結果を解釈する方法を次に示します。

switch (r[1]) {
  case EOF: // empty string
    break;
  case 0: // doesn't start with numeric characters
    break;
  case 1: // starts with number; sscanf follows standards
  case 2: // starts with number; sscanf follows TC1
    if (c[chars_read] == '\0')
      r[1] = 1; // we read entire string
    else
      r[1] = 0; // didn't read entire string; pretend we read nothing
    break;
  default: // shouldn't happen
    assert(FALSE);
}
于 2012-05-17T17:23:13.930 に答える
3

C を使用strtolしている場合は、一時的な変換と呼ばれるものを使用できます。変換できるデータの末尾へのポインターが表示されます。それが文字列の最後ではない場合、変換できるものの後に少なくともいくつかのゴミがありました。

C++ を使用している場合は、おそらく Boost を使用することをお勧めします。lexical_castこれは、入力全体が変換先の型に変換された場合は成功しますが、変換されなかったものがある場合は例外をスローします。

于 2012-05-17T17:24:06.107 に答える