0

以下のコードが失敗する理由がわかりません:

char    toto[54], titi[54]; //I already tried with allocations

sscanf_s(line, "%s-%s", &toto, &titi, sizeof(toto) + sizeof(titi));

また

sscanf_s(line, "%s-%s", &toto, &titi, sizeof(toto) + sizeof(titi));

私の問題は文字列のみ (float、int、double などは問題ありません) で、Visual 2010 を使用しています。

誰にもアイデアはありますか?ご回答ありがとうございます。

4

2 に答える 2

5

sscanf_s()リファレンスページから:

sscanf_s関数は、バッファから各引数で指定された場所にデータを読み取ります。format文字列の後の引数は、formatの型指定子に対応する型を持つ変数へのポインターを指定します。安全性の低いバージョンのsscanfとは異なり、タイプフィールド文字c、C、s、S、および[を使用する場合は、バッファサイズパラメータが必要です。文字単位のバッファサイズは、それを必要とする各バッファの後に追加パラメータとして指定する必要があります。詳細については、scanf_s、_scanf_s_l、wscanf_s、_wscanf_s_l、およびscanfタイプフィールド文字を参照してください。

つまり、各バッファの後にそのサイズを続ける必要があります。

sscanf_s(line, "%s-%s", toto, sizeof(toto), titi, sizeof(titi));

さらに、-空白ではない文字は"%s"フォーマット指定子のターミネータとして機能しないため、line含まれている場合hello-worldは読み込まれtototiti割り当てられません。-ターミネータとして使用するには、スキャンセットを使用します。

if (2 == sscanf_s(line, "%[^-]-%s", toto, sizeof(toto), titi, sizeof(titi)))
{
    /* Both 'toto' and 'titi' where assigned. */
}
于 2012-11-07T22:20:43.130 に答える
0

明らかsscanf_s()に変な場合を除き、配列へのポインター ( &toto) ではなく、配列の最初の要素へのポインター( ) を渡しますtoto。また、安全な関数の目的は、バッファ オーバーランを回避することです。つまり、バッファに含まれる文字数を個々のバッファごとに指定する必要があります。

if (sscanf_s(line, "%s-%s", toto, sizeof(toto), titi, sizeof(titi)) == 2) {
    ...
}

(データを処理する前にエラーが発生したかどうかを読み取りの試行で常に確認する必要があるため、エラー処理)

個人的には、std::istringstream文字列と適切なカスタム マニピュレータを組み合わせて使用​​し、問題を完全に回避します。

std::istream& minus(std::istream& in) {
    if ((in >> std::ws).peek() != std::char_traits<char>::to_int_type('-')) {
        in.setstate(std::ios_base::failbit);
    }
    else {
        in.ignore();
    }
    return in;
}

std::string toto, titi;
if (std::istringstream(line) >> std::skipws >> toto >> minus >> titi)) {
    ...
}
于 2012-11-07T22:27:03.047 に答える