C, указатели, консоль исчезает при вводе данных - PullRequest
2 голосов
/ 12 июня 2011

Привет и заранее спасибо,

Короче говоря, я создаю указатель, который создает локальную переменную в стеке, а затем запрашиваю память с помощью 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 ]

5 голосов
/ 12 июня 2011

scanf("%d", grade); должно быть scanf("%d", &grade);

Вы должны передать адрес переменной / буфера, где вы хотите сохранить элемент ввода.И grade относится к содержимому, там оператор & addressof, работающий на grade &grade, дает нам адрес переменной.

В случае scanf("%s", student); student сам относится к адресу, то есть к содержимому переменной-указателя student, которая содержит базовый адрес блока памяти, который вы только что выделили.Поэтому это правильно.

Аргументы всегда должны указывать на адрес расположения переменной / буфера, куда вы хотите, чтобы scanf поместил этот конкретный раздел этого ввода.

Скажем, изначально у вас есть мусор 0x5964, хранящийся в grade, а адрес памяти grade равен 0x1234abcdscanf ("%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  | 
   +----------+
2 голосов
/ 12 июня 2011

Вы должны использовать scanf("%d", &grade);.scanf() нужно знать , где для записи данных, поэтому ему нужен адрес переменной.

2 голосов
/ 12 июня 2011

Ваш комментарий неверный, он должен быть &grade, потому что вам нужно передать адрес из grade, чтобы scanf мог изменить его через адрес памяти.Если вы передадите просто grade, вы передадите scanf значение из grade, что представляет собой случайный мусор (или возможный 0 в зависимости от вашего компилятора), потому что вы его не инициализировали.scanf затем думает, что случайное число (или 0 ...) является адресом, и пытается изменить память по этому адресу, что приводит к сбою.

Чтобы getchar приостановил программу,позвоните fflush(stdin) после второго звонка scanf.

0 голосов
/ 13 июня 2011

Сбой или просто печать результата?
Как сбои?

В любом случае (после добавления оператора address-of в 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, чтобы указать на эту ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...