【问题标题】:problems with scanf and conversion specifiersscanf 和转换说明符的问题
【发布时间】:2014-09-18 23:02:27
【问题描述】:

这里你可以看到我的源代码:

#include <stdio.h>

int main()
{
    char yourname;
    char yoursex;
    int yourage = 0;

    printf("Hey, what's your name?\n");
    printf("My name is: ");
    scanf("%s", &yourname);
    printf("Oh, hello %s! \n\n", &yourname);

    printf("Are you a boy or a girl?: ");
    scanf("%s", &yoursex);
    printf("Nice to know you are a %s! \n\n", &yoursex);

    printf("How old are you %s? I am ", &yourname);
    scanf("%d", &yourage);
    printf("I see you are %d, you have many years then!", &yourage);

    return 0;
}

我正在尝试我不知道的事情,但奇怪的是它对我不起作用。有什么问题?另外,为什么它需要是 %s 而不是 %c?如果我使用 %c 代替它不起作用!

上面写着: 你 %s 几岁?它没有写我的名字,而是说''oy''

最后一行没有显示我的年龄,而是显示了一个大数字。

【问题讨论】:

  • char 表示一个字符。您不能在其中存储名称。

标签: c printf scanf


【解决方案1】:

这些是 C 编程的基础知识,我强烈建议你买一本像样的书 - Dennis Ritchie 的《C 编程语言》将是一个好的开始。

您的代码中有许多错误。

  1. char 只能包含一个字符,例如“A”或“a”或类似的东西。当您扫描名称时,它将是一组字符,例如“E”、“d”、“d”、“y”。要存储多个字符,您需要使用字符数组。此外,用于扫描/打印字符的格式说明符是%c%s 用于需要将一组字符(也称为字符串)扫描成数组。

  2. 当您使用printf 时,您不会提供指向您尝试打印的变量的指针(&amp;x 是指向变量x 的指针)。指针是一个 32/64 位整数,这可能是您在尝试打印时看到随机整数的原因。 printf("%c\n", charVar) 就足够了。

  3. scanf 在使用%s 作为格式说明符时不需要&amp;,假设您已将字符数组作为参数传递。原因是,scanf 需要知道将您从输入中读取的数据存储在哪里——这是由指向内存位置的指针给出的。当你需要扫描一个整数时,你需要传递一个&amp;x——这意味着,指向x的内存位置的指针。但是当你传递一个字符数组时,它已经是内存地址的形式了,不需要在前面加上一个&。

我再次建议您在网上查找一些不错的教程,或者买一本书(我上面提到的那本是经典的)。键入材料中给出的示例。实验。玩得开心。 :)

【讨论】:

    【解决方案2】:

    %s 用于读取字符串——多个字符由空格分隔。 %c 用于读取单个字符。

    您将yournameyoursex 变量声明为字符,然后尝试将字符串读入其中。读取的字符串将覆盖堆栈帧中的随机其他内容并出现异常或崩溃。

    您想将yournameyoursex 声明为字符数组,以便它们可以保存字符串:

    char yourname[32];
    char yoursex[32];
    

    然后,在读入它们时,您希望包含一个长度限制,以免它们溢出:

    scanf("%31s", yourname);
    

    【讨论】:

      【解决方案3】:

      这是一个字符

      char yourname;
      

      %s 表示该变量是一个字符串(即以NUL 结尾的字符数组)。这就是您需要%c 的原因。如果你真的想使用一个字符串,那么定义变量就像

      char yourname[32];  /* just pick a big enough size */
      

      另外,使用scanf() 的变量的地址 是正确的,但printf() 需要该值。所以不是

      printf("I see you are %d, you have many years then!", &yourage);
      

      使用

      printf("I see you are %d, you have many years then!", yourage);
      

      “大数”是内存地址。

      【讨论】:

        【解决方案4】:

        确保您阅读了代码中的 cmets!

        #include <stdio.h>
        
        int main()
        {
            char yourname[10];
            char yoursex[5]; // boy or girl + null terminator
            int yourage = 0;
        
            printf("Hey, what's your name?\n");
            printf("My name is: ");
            scanf("%s", &(*yourname)); // & and * cancel each other out,
            // thus take a look at the next scanf()
            printf("Oh, hello %s! \n\n", yourname); // yourname is now an array
        
            printf("Are you a boy or a girl?: ");
            scanf("%s", yoursex);
            printf("Nice to know you are a %s! \n\n", yoursex);
        
            printf("How old are you %s? I am ", yourname);
            scanf("%d", &yourage); // ok
            printf("I see you are %d, you have many years then!", yourage); // here you don't
            // need the address of the variable!
        
            return 0;
        }
        

        【讨论】:

          【解决方案5】:

          表达式char yourname; 仅保留单个字符的空间,因此很可能在扫描您的姓名时最终破坏了内存空间。您应该分配一个更大的缓冲区,并通过设置使用 scanf 函数读取的最大字符数来确保不会超出其长度;如其他一些答案中所述。

          以下printf 正确打印名称的事实并不意味着内存没有损坏;因为 C/C++ 不会真正检查运行时使用的任何字符串或数组的边界。

          正如其他人所建议的,从阅读一本关于 C 和/或 C++ 的好书开始并不是一个坏主意。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-09-28
            • 1970-01-01
            • 1970-01-01
            • 2020-04-13
            • 1970-01-01
            • 1970-01-01
            • 2023-02-10
            • 2013-12-20
            相关资源
            最近更新 更多