1
#include<stdio.h>
int main()
{    
    char str[50]={'\0'};
    scanf("%[A-Z]s",str);  
    printf("%s",str);        
    return 0;
}

1) 入力:

こんにちは世界

出力:

2) 入力:

こんにちは世界

出力:

地獄

出力 1 では、出力が "WORLD" であると予想していましたが、何も出力されませんでした。出力 2 から、これは最初の数文字が大文字の場合にのみ機能することがわかりました。

それが実際にどのように機能するか説明していただけますか?

4

2 に答える 2

2

scanset の解釈

が与えられた場合、は大文字ではないためhelloWORLD、変換指定%[A-Z]はすぐに失敗します。hしたがって、scanf()何も変換できなかったことを示す 0 を返します。戻り値をテストした場合は、それがわかります。

それが与えられるHELLoworlDと、scanset は に一致HELLし、最初で停止しoます。フォーマット文字列もリテラルに一致させようとしますが、一致後に一致しなかったことを が報告するs方法はありません。scanf()HELL


バッファオーバーフロー

は、読み取られる文字数に制限がないため%[A-Z]、一般に (そのままで) 危険であることに注意してください。%sあなたが持っている場合:

char str[50];

次に、次を使用する必要があります。

if (scanf("%49[A-Z]", str) != 1)
    ...some problem in the scan...

strまた、宣言された長さとフォーマット文字列の数値の間には「1 の違い」があることに注意してください。これは厄介です。フォーマット文字列とは異なり、引数としてその数値を指定する方法はないためscanf()( とは異なりprintf())、その場でフォーマット文字列を作成することになる場合があります。

int scan_upper(char *buffer, size_t buflen)
{
    char format[16];
    if (buflen < 2)
        return EOF;  // Or other error indication
    snprintf(format, sizeof(format), "%%%zu[A-Z]", buflen-1);  // Check this too!?
    return scanf(format, buffer);
}
于 2013-07-05T06:13:15.113 に答える
1

あなたがするとき

scanf("%[A-Z]s",str);

大文字を入力する限り、入力が必要です。また、すべての配列を に設定しているため、配列が'\0'一致printf()すると印刷が停止します。

したがって、最初の入力は空白で、2 番目の入力は大文字の文字列の最後まで出力されます。

于 2013-07-05T05:07:31.717 に答える