C编程 - Scanf无法正常工作。尝试增加空间,不起作用

时间:2017-12-22 17:59:40

标签: c scanf

int main(int argc, char *argv[]) {
     int option;
     char user[50];

    system("COLOR b");

    printf("~~~~~~~~~~~~~~~~ GLENMUIR HIGH SCHOOL LIBRARY MANAGEMENT SYSTEM ~~~~~~~~~~~~~~~~~~~~~~~ \n");
    printf("Username:");
    scanf("%c",&user);

    checkPass();
    printf("\n |                          Options Menu                                 |\n");
    printf(" | Check Out Book(1), Return Book(2) , Register(3), Admin Login (4)      |\n");

    printf("Option:");

    scanf("%d",&option); /*compiler ignores this completely*/

我尝试在%d之前添加空格,但仍然无效。有关newb的任何解决方案吗?

2 个答案:

答案 0 :(得分:0)

来自转化说明符下的标准7.21.6.2及其含义:

  

s   匹配一系列非空白字符.286)如果没有l长度   修饰符存在,相应的参数应为指针   字符数组的初始元素足以接受   序列和终止空字符,将被添加   自动。

作为scanf的替代方案,您可以尝试查看fgets

因此,答案将是scanf("%s",user);或更正确的使用scanf("%49s",user)。为了更好地了解为什么您应该考虑fgets而不是scanf,请仔细阅读discussion

此外,无需在%d格式说明符之前放置空格,因为根据标准7.21.6.2

  

输入空白字符(由isspace函数指定)   被跳过,除非规范包含[cn说明符

除了上面提到的更改之外,请检查scanf的返回值。

if( scanf("%49s",user) != 1){
  fprintf(stderr,"You have given wrong input - use input just a word\n");
  exit(1);
}

在您的情况下,如果您输入了错误,那么这将失败,您将收到错误消息。

您可以像%d这样使用scanf说明符,无需提供' '

if( scanf("%d",&option)!= 1){
   /* handle error. Put appropriate meaningful error message. */
   exit(1);
}

同样在Dev-cpp中尝试添加编译器标志-Wall -Wextra,它将显示警告。

  • 转到工具 - >编译器选项

  • 现在位于general下的Adds the following command when compiler is called标签和-Wall -Wextra and press OK,=。

编译它。你会得到一些这样的错误 - [警告]格式%c期望类型为char *的参数,但参数2的类型为char (*)[20] [-Wformat =]`

&user表示指向包含20个字符的char数组的指针。但如上所述,您必须将char*作为第二个参数传递给scanf

答案 1 :(得分:0)

你的问题源自这句话:

scanf("%c",&user);

%c转换说明符仅从输入流中读取单个字符,而不是字符串。如果您输入了jbode这样的用户名,则只会从输入流中读取'j'字符 - 其余字符将由 next scanf读取(或其他输入)来电。

不幸的是,由于scanf转换说明符,下一个%d调用期待一个十进制数字序列; 'b'不是十进制数字,因此您得到匹配失败 - option未更新,'b'未从输入流中删除,scanf 1}}返回0表示没有成功转换。

正确的答案是不要使用scanf来读取用户名,而是使用fgets代替:

if ( !fgets( user, sizeof user, stdin ) )
{
  // EOF or error detected on input, handle as appropriate
}

checkPass();
...

如果你真的想使用scanf,那么正确的做法是:

if ( scanf( "%49s", user ) != 1 ) // no & operator on user
{
  // EOF or error detected on input, handle as appropriate
}

checkPass();
...

将字符串读入&数组时,无需使用char运算符。 表达式 user将隐式转换(" decay")从类型char [50]转换为char *,结果指针值将是数组的第一个元素的地址。