很少有关于C的新手问题,scanf和转换说明符的问题

时间:2014-09-18 23:02:28

标签: c printf scanf

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

#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而不是它不起作用!

它说: 你多大了几岁?而不是说出我的名字,它说&#39; oy&#39;&#39;

而不是在最后一行显示我的年龄,它显示了一个很大的数字。

非常感谢,编程很复杂,但非常有益:)

5 个答案:

答案 0 :(得分:2)

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

您的代码中存在许多错误。

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

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

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

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

答案 1 :(得分:1)

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

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

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

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

然后,在阅读它们时,您想要包含一个长度限制,以便它们不会溢出:

scanf("%31s", yourname);

答案 2 :(得分:0)

这是一个字符

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);

“大号”是内存地址。

答案 3 :(得分:0)

请务必阅读代码中的评论!

#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;
}

答案 4 :(得分:0)

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

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

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