if (scanf("%" NAME_MAX_S "[^\n]", name) != 1) // This line
それは書き方です:
if (scanf("%80[^\n]", name) != 1)
あなたを混乱させる可能性のある複数の機能があります。
- この
"%" NAME_MAX_S "[^\n]"
表記法では、文字列の連結を使用して、断片から単一の文字列を作成します。
- 変換指定では、否定された
%80[^\n]
「スキャン セット」を使用して、読み取り文字列が最大 80 個の非改行であることを指定します。
- またはで
scanf()
et al に長さを指定する場合、ヌルバイトを除いた文字数を指定します (旧設計)。これは、文字列変数の定義されたサイズと変換仕様で指定された長さの間の 1 つずつずれを処理する必要があることを意味します。%s
%[]
- 全体的な条件は、文字列が正常に読み取られたことを正しくチェックします。変換の失敗 (入力の最初の文字が改行であるため戻り値 0) と EOF を検出します。唯一の考えられる問題は、2 つを区別するために戻り値を保持しないことですが、 and を使用
feof()
しferror()
てそうすることができます。これが意図されていることです (何かが失敗した後のエラーを区別するため)。
このコードNAME_MAX_S
は、文字列があることを確認するために使用します。使用できた可能性があります:
#define STR_EVALUATE(x) #x
#define STRINGIFY(x) STR_EVALUATE(x)
if (scanf("%" STRINGIFY(NAME_MAX) "[^\n]", name) != 1)
これにより、保持する行数が 1 に減ります。ただし、単純な数値に対してのみ機能します。式がある場合#define NAME_MAX (2*LEN_NAME_COMPONENT+LEN_MIDDLE_INITIALS)
、文字列形成のプロセス全体が機能しません。次に、次のことを行う必要があります。
char format[16];
sprintf(format, "%%%d[^\n]", NAME_MAX);
if (scanf(format, name) != 1)