【问题标题】:scanf("%s") stores string even after using it after scanf("%d")scanf("%s") 存储字符串,即使在 scanf("%d") 之后使用它
【发布时间】:2017-06-11 20:22:06
【问题描述】:

所以我写了这段代码(忽略缓冲区溢出问题,因为这只是一个简单的例子):

#include<stdio.h>
int main(void){
    int n;
    char s[10];
    printf("Enter a number: ");
    scanf("%d",&n);
    scanf("%s",s);
    printf("%s",s);
    return 0;
}

字符串不应该存储在数组中,因为输入缓冲区中应该有一个“\n”,因此应该终止 scanf("%s",s) 但事实并非如此。输出打印字符串。

【问题讨论】:

  • @xing 非常感谢。我不知道。
  • 通常,它只会导致后续的"%c" 格式说明符出现问题,除非使用" %c" 明确指示,否则它不会自动跳过前导空格。
  • "...因为输入缓冲区中应该有一个"\n"..." - 你从哪里得到这个想法? scanf 根本不关心 \n。对于scanf \n 只是另一个空白字符。
  • @AnT scanf 确实关心带有 %c、%n 和 %[ 的空格

标签: c scanf


【解决方案1】:

格式说明符%s 会跳过前导空格,即任何'\n'' ''\t'、...都将被忽略,s[0] 将包含输入的第一个非空格。

为了稍微演示一下scanf 中发生的事情,请参阅下面的示例,该示例利用scanf"%n" 功能,返回到目前为止已处理的字符数;我使用了sscanf,结果不依赖于用户输入。请注意,在读取字符串时,scanf 处理的字符多于结果中存储的字符:

#include<stdio.h>
int main(void){
    int n;
    int pos;
    char s[10];
    const char* simulatedInput = "123\n     abcde";
    const char* inputPtr = simulatedInput;

    sscanf(inputPtr,"%d%n",&n,&pos);
    printf("sscanf on %s processed %d charaters; result n: %d\n", inputPtr, pos, n);

    inputPtr += pos;  // inputPtr will point at the position of '\n'
    sscanf(inputPtr,"%s%n",s,&pos);
    printf("sscanf on %s processed %d charaters; yet s as '%s' contains only %lu characters\n", inputPtr, pos, s, strlen(s));

    return 0;
}

输出:

sscanf on 123
     abcde processed 3 charaters; result n: 123
sscanf on 
     abcde processed 11 charaters; yet s as 'abcde' contains only 5 characters

【讨论】:

  • 只是一个挑剔:scanf() 的 POSIX 规范在未标记为 POSIX 扩展的部分中说“空白”包括换页符'\f' 和垂直制表符'\v'以及空白、制表符和换行符。这不是一个大问题。你也很少遇到。 ('奇怪的是,C 标准将回车 '\r' 添加到默认 (C) 语言环境中 isspace() 识别的字符列表中。C 标准说“空白”而不列出字符;这意味着“什么 @ 987654339@ 说是空白”。)
猜你喜欢
  • 2017-02-11
  • 2011-01-10
  • 2017-08-19
  • 2017-08-26
  • 2019-07-02
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多