1

uC++ では、文字列から整数を読み取る場合、またはdを変換指定子として使用するかどうかは問題ではないようです。両方とも負の整数を受け入れるからです。

#include <cstdio>
using namespace std;

int main() {
    int u, d;
    sscanf("-2", "%u", &u);
    sscanf("-2", "%d", &d);
    puts(u == d ? "u == d" : "u != d");
    printf("u: %u %d\n", u, u);
    printf("d: %u %d\n", d, d);
    return 0;
}

Ideone.com

違いがあるかどうかをさらに掘り下げました。見つけた

int u, d;
sscanf("-2", "%u", &u);
sscanf("-2", "%d", &d);

と同等です

int u, d;
u = strtoul("-2", NULL, 10);
d = strtol("-2", NULL, 10);

cppreference.comによると。

これらの変換指定子を解析に使用する場合、つまり-type 関数に渡される形式に違いはありuますか? それは何ですか?dscanf

CでもC++でも答えは同じですよね?そうでない場合は、両方に興味があります。

4

3 に答える 3

9

%d: 整数を 10 進数としてスキャンしますsigned int同様の変換指定子 は%i、 が前にある場合は数値を 16 進数として解釈し、 が前にある0x場合は 8 進数として解釈し0ます。それ以外は同一です。

%u: 整数を 10 進数としてスキャンしますunsigned int

于 2016-02-09T15:46:17.630 に答える
1

変換指定子には、C 仕様で定義された結果引数の対応する型があります。および変換ディレクティブは実際%u%dは同じ入力を受け入れますが、観察したように、に対応する引数は型ではなく%u、型でなければなりunsigned int*ませんint*。つまり、あなたの例は次のように修正する必要があります。

unsigned int u;
int d;
sscanf("-2", "%u", &u);
sscanf("-2", "%d", &d);

警告を有効にした場合、元の例をコンパイルするときに警告が表示されます。そして当然のことです:

代入の抑止が * で示されていなければ、変換結果は、まだ変換結果を受け取っていない format 引数に続く最初の引数が指すオブジェクトに配置されます。このオブジェクトに適切な型がない場合、または変換の結果をオブジェクトで表すことができない場合、動作は未定義です。

鉱山を強調します。

したがって、未定義の動作を呼び出していました (未定義の動作とはの部分を参照してください)。未定義の動作を呼び出すと、孤独になり、厄介なことが起こる可能性があります。


変換修飾子は、C99 (最新のパブリック ドラフト、N1256;公式 PDF ) で定義されています。定義はC11 (最新のパブリック ドラフト、N1570;公式 PDF ) と同じです。スタック オーバーフローの別の質問の下にある C++ 標準ドキュメントのリストからリンクされている最新の C++ ドラフト(2015 年 2 月 10 日現在、N4567) は、C99 からヘッダーの定義を取得し、それを変更しません(関数を名前空間と§ 27.9.2で言及されているマイナーな変更)。cstdiostd

于 2016-02-10T17:28:54.667 に答える
1

技術的には、フォーマット指定子を使用して負の数を読み込もうとすると、未定義の動作が発生します。符号付き整数へのポインタを符号なし整数へのポインタとして扱うようにしますが、これらの型には互換性がありません。符号なし整数と符号付き整数の両方が同様のビット表現を持ち、符号付き整数が 2 の補数表現を使用するためにのみ機能します。int%usscanf

TL/DR: から -2 を得る保証はありません。sscanf("-2", "%u", &u);

于 2016-02-09T16:10:59.173 に答える