6

数値を表す文字列を指定して、文字列全体が変換されなかった場合に通知を提供する変換関数に入れたいと思います。

入力用: "12":

  • istringstream::operator>>出力 12
  • atoi出力 12
  • stoi出力 12

入力について"1X"は、失敗の応答が必要ですが、次のようになります。

  • istringstream::operator>>出力 1
  • atoi出力 1
  • stoi出力 1

入力の場合"X2":

  • istringstream::operator>>0 を出力し、エラーフラグを設定します
  • atoi出力 0
  • stoiエラーをスローします

実例

入力時にエラー動作を引き起こす方法はあります"1X"か?

4

2 に答える 2

3

編集:以降がfrom_chars推奨されます。詳細については、こちらを参照してください: https://topanswers.xyz/cplusplus?q=724#a839


これを達成するstring str方法はいくつかあり、それぞれに長所と短所があります。https://ideone.com/LO2Qnqに実際の例を書き、以下でそれぞれについて説明します。

strtol

示唆されているように、 here strtolの out-parameter を使用して、読み取った文字数を取得できます。strtol実際にはlongan ではなくa を返すintため、戻り時にキャストが行われます。

char* size;
const int num = strtol(str.c_str(), &size, 10);

if(distance(str.c_str(), const_cast<const char*>(size)) == str.size()) {
    cout << "strtol: " << num << endl;
} else {
    cout << "strtol: error\n";
}

str.c_str()これは同じ文字列を参照するために使用されることに注意してください。c_strC++11 を使用している場合、一時的ではなく、文字ストレージとして機能する基になる配列へのポインターを返します。

c_str()data()同じ機能を実行します

また、次の場合を除き、 によって返されるポインターはとの呼び出しc_strの間で有効であることに注意してください。strtoldistance

  • への非const参照をstring標準ライブラリ関数に渡す
  • 、、、、、、、およびconst_ string_ operator[]_ at()_ front()_ back()_ begin()_ rbegin()_end()rend()

これらのケースのいずれかに違反した場合は、iの基礎const char*となる の一時的なコピーを作成し、その上でテストを実行する必要があります。

sscanf

sscanfを使用%znして、読み取った文字数を返すことができます。これは、ポインター比較を行うよりも直感的です。ベースが重要な場合はsscanf、適切な選択ではない可能性があります。基数 2 ~ 36 をサポートするstrtolおよびとは異なり、8 進数 ( )、10 進数 ( )、および 16 進数( )のみの指定子を提供します。stoisscanf%o%d%x

size_t size;
int num;

if(sscanf(str.c_str(), "%d%zn", &num, &size) == 1 && size == str.size()) {
    cout << "sscanf: " << num << endl;
} else {
    cout << "sscanf: error\n";
}

stoi

示唆されているように、 herestoi出力パラメータは、 が読み取った文字数を返すように機能します。C++ に合わせて、これは を取り、上記の C 実装とは異なり、空白以外の最初の文字が現在のベースの数字と見なされない場合にスローします。とブロック。sscanf%nstringstoiinvalid_argumenttrycatch

try {
    size_t size;
    const auto num = stoi(str, &size);

    if(size == str.size()) {
        cout << "stoi: " << num << endl;
    } else {
        throw invalid_argument("invalid stoi argument");
    }
} catch(const invalid_argument& /*e*/) {
    cout << "stoi: error\n";
}
于 2015-10-07T16:39:10.817 に答える