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

扫描集的解释

When it is given helloWORLD, the conversion specification %[A-Z] fails immediately because the h is not an upper-case letter. Therefore, scanf() returns 0, indicating that it did not successfully convert anything. If you tested the return value, you'd know that.

When it is given HELLoworlD, the scanset matches the HELL and stops at the first o. The format string also attempts to match a literal s, but there's no way for scanf() to report that it fails to match that after matching HELL.


Buffer overflow

Note that %[A-Z] is in general dangerous (as is %s) because there is no constraint on the number of characters read. If you have:

char str[50];

then you should use:

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

Also note that there is a 'difference by one' between the declared length of str and the number in the format string. This is awkward; there's no way to provide that number as an argument to scanf() separate from the format string (unlike printf()), so you may end up creating the format string on the fly:

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()当它遇到一个时将停止打印。

因此,第一个输入为空白,第二个输入打印到大写字符串的末尾。

于 2013-07-05T05:07:31.717 回答