【问题标题】:scanf on Visual Studio 2015Visual Studio 2015 上的 scanf
【发布时间】:2016-12-02 08:33:20
【问题描述】:
void loginForm() {
    char username[100], password[100];
    printf("Username: ");
    scanf("%[^\n]", username);
    printf("%s", username);
    printf("Password: ");
    scanf("%[^\n]", password);
    printf("%s", password);
}

我在 VS2015 中遇到了这段代码的问题,每次我输入我的用户名时它都会造成严重破坏,就像这样:

Username: Tenzo
Password: Tenzo╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠Tenzo

我很困惑,因为在代码中,我想在要求用户输入密码之前先打印“用户名”,但正如你所见,我什至没有输入任何密码,但你可以看到它已经看起来像那样了。 在 VS2010 上测试了代码,一切正常。我不知道发生了什么。

注意:代码是用 C 编写的,而不是 C++。

【问题讨论】:

  • 尝试在百分号前加一个空格:" %[^\n]"。此外,您不需要在 scanfs 中的 usernamepassword 前面添加与号。
  • 糟糕,很抱歉我没有注意到与号。我删除了那个。哇,这行得通!您可能想使用回答模式来回复有关正在发生的事情的更多信息,因为我无法将评论设置为答案:)
  • scanf 函数停止读取空格(如换行符)。输入缓冲区中的换行符不会被复制到您提供的缓冲区中。所以一个简单的"%99s" 格式应该足以满足您的scanf 调用。事实上,使用"%[" 格式会导致问题,因为它不会跳过前导空格。所以第二个scanf 调用将读取前一个调用的换行符。
  • @Someprogrammerdude 我知道这一点,但是空格算作空格吗?由于用户名和密码也可能包含空格。还有关于第二个scanf,我确实在每个scanf之后都放了fflush(stdin),我只是不在这里展示它们,够了吗?
  • 啊,是的,空格当然是空格字符。然后,您的格式字符串需要包含 @user3386109 建议的前导空格,以丢弃前导空格(如前面的输入换行符)。

标签: c visual-studio-2010 visual-studio-2015 printf scanf


【解决方案1】:

问题在于"%[^\n]" 格式说明符会将换行符留在输入缓冲区中。以下scanf 不会跳过该换行符,因为%[] 格式说明符默认情况下不会跳过前导空格。 (相比之下,大多数格式说明符,如 %s%d%fdo 默认跳过空格。)

为了解决问题,可以在格式字符串的开头放一个空格,像这样

scanf(" %[^\n]", password);
       ^ this space forces scanf to skip any leading whitespace, including newlines

【讨论】:

  • 感谢您的回答和您的时间来解释事情! :) 顺便说一句,每次 scanf 后 fflush(stdin) 是否可以正常工作?
  • @TenzoNakami 根据 C 规范,fflush 仅允许用于输出流和更新流(第 7.21.5.2 节)。但是Microsoft allows it on input streams,所以我让你来决定。
  • 嗯,我刚才试过了,但它不起作用。好吧,那我就坚持你的回答! :)
猜你喜欢
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2015-10-23
  • 2016-07-22
  • 1970-01-01
  • 2017-04-24
相关资源
最近更新 更多