C,指针,控制台在输入数据时消失

时间:2011-06-12 16:53:29

标签: c pointers

您好,并提前致谢,

简而言之,我所做的是创建一个指针,在Stack上创建一个局部变量,然后我通过malloc请求内存,它在堆中分配空间。

然后我在堆栈上创建一个本地int。

然后我通过scanf请求用户输入。

但输入最后一位数后,即使我试图通过getchar()

,控制台也会消失并且不会打印结果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 80

int main()
{
    char *student = malloc(MAX_LINE * sizeof(char));
    int grade;

    printf("Enter students name ");
    scanf("%s", student);

    printf("Enter students grade ");
    scanf("%d", grade);// i would say it has to be grade and not &grade
    // it vanishes right after here. Cant get to see any result
     printf("%s received a %d\n", student, grade);

    free(student);
    getchar();



}

4 个答案:

答案 0 :(得分:5)

scanf("%d", grade);应为scanf("%d", &grade);

您应该传递要存储输入元素的变量/缓冲区的地址。并且grade指的是内容,& grade运算符&grade地址为我们提供了变量的地址。

scanf("%s", student);的情况下,student本身引用地址,即指针变量student的内容,其中包含刚分配的内存块的基址。因此这是正确的。

参数应始终指向变量/缓冲区位置的地址,您希望scanf放置该输入的特定部分。

假设您最初在0x5964中存储了垃圾grade,并且grade的内存地址为0x1234abcd。在scanf ("%d", grade);中,scanf会尝试将读取整数写入内存位置0x5964,这是无效的。

而在scanf ("%d", &grade);中,scanf会将读取整数存储到内存位置0x1234abcd。在此之后引用grade作为r值将获得内存位置0x1234abcd上的内容,这就是您想要的。

   +----------+                                   
   | 0x5964   |  <-------(uses this as address)---+-------------------+
   +----------+  <------+                         |                   |
   |  grade   |     (writes)       scanf ("%d", grade);               |  
   +----------+      (here)        scanf ("%d", &grade);              |
   |0x1234abcd|         |                         |                   |
   +----------+  <------+(uses this as address)---+                   |
                                                                      |
                                                                      |
   +----------+                                                       |
   |  ??????  | <----------(tries to write here)----------------------+
   +----------+
   |   ???    |
   +----------+
   |  0x5964  | 
   +----------+

答案 1 :(得分:2)

您的评论不正确,需要&grade,因为您需要传递grade地址,以便scanf可以通过内存修改它地址。如果您仅传递grade,则传递scanf grade,这是一些随机垃圾(或者可能为0,具体取决于您的编译器),因为你没有初始化它。 scanf然后认为随机数(或0 ...)是一个地址并试图修改该地址的内存,这会导致崩溃。

要让getchar暂停该计划,请在第二次致电fflush(stdin)后致电scanf

答案 2 :(得分:2)

您应该使用scanf("%d", &grade);scanf()需要知道 where 来写数据,因此它需要变量的地址。

答案 3 :(得分:0)

是崩溃还是不打印结果?
它是如何崩溃的?

无论如何(在向grade添加地址运算符之后),您应该始终检查scanf的返回值。在这种情况下,如果一切正常则返回1,否则返回0(或EOF)。

int chk = scanf("%d", &grade);
if (chk == 1) {
    /* rest of your program */
} else {
    fprintf(stderr, "something went wrong in the scanf.\n");
    fprintf(stderr, "Return value was %d\n", chk);
}

我怀疑您输入了带有嵌入空格的名称(例如"full name")。这样做会将"full"分配给student并将" name"留在缓冲区中,以备下次输入操作。尝试从那里获取一个整数将失败,scanf返回0表示失败。