c中的输入/输出扫描集

时间:2013-07-05 04:59:07

标签: c scanf

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

1) 输入:

  

的HelloWorld

输出:

  

2) 输入:

  

的HelloWorld

输出:

  

HELL

在输出1中,我预计输出为“世界”,但它没有给出任何结果。 从输出2,我明白只有前几个字符是大写字母才能正常工作。

你能解释它是如何运作的吗?

2 个答案:

答案 0 :(得分:2)

扫描集的解释

当给出helloWORLD时,转换规范%[A-Z]会立即失败,因为h不是大写字母。因此,scanf()返回0,表示它没有成功转换任何内容。如果你测试了返回值,你就会知道。

如果给出HELLoworlD,则扫描集与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);
}

答案 1 :(得分:1)

当你这样做时

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

只要输入大写字母,它就会输入。 由于您将所有数组设置为'\0'printf()会在遇到一个时停止打印。

因此,第一个输入为空白,第二个输入打印直到大写字符串结束。