【问题标题】:C Programming- Scanf not working. Tried adding space, doesnt work [closed]C 编程 - Scanf 不工作。尝试添加空间,不起作用[关闭]
【发布时间】:2017-12-22 17:59:39
【问题描述】:
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 之前添加空格,但仍然无效。新手有什么解决办法吗?

【问题讨论】:

  • 它应该给你一些警告......
  • 不要使用scanf。如果您只想读取一个字符,请使用getcfgetcgetchar。要读取整数,请使用fgetsstrtol。作为新手,完全避免scanf
  • 他想读取用户名,所以 scanf 是正确的。但是不知道他是否需要先打开标准输入再使用fscanf?
  • 最后一个scanf不起作用
  • 我没有收到任何警告

标签: c scanf


【解决方案1】:

您的问题源于以下陈述:

scanf("%c",&user);

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

不幸的是,由于%d 转换说明符,下一个scanf 调用需要一个十进制数字序列; 'b' 不是十进制数字,所以你得到一个匹配失败 - option 没有更新,'b' 没有从输入流中删除,scanf 返回一个 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 将隐式地从char [50] 类型转换(“衰减”)为char *,结果指针值将是数组第一个元素的地址。

【讨论】:

    【解决方案2】:

    来自标准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);
    }
    

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

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

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

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

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

    • 现在在Adds the following command when compiler is called 下的general 标签和-Wall -Wextraand pressOK`,=。

    编译它。您将收到类似这样的错误 - [警告] 格式 %c 需要 char * 类型的参数,但参数 2 的类型为 char (*)[20] [-Wformat=]`

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-10
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多