scanf_s выдает исключение - PullRequest
3 голосов
/ 28 февраля 2010

Почему следующий код вызывает исключение при переходе ко второму scanf_s после ввода числа для помещения в структуру.

Это ни в коем случае не представляет собой полную реализацию связанного списка.

Не знаете, как попасть на следующую scanf_s при вводе значения? Есть идеи?

РЕДАКТИРОВАТЬ: обновленный код с предлагаемым решением, но все равно получить AccessViolationException после первого scanf_s

Код:

struct node
{
    char name[20];
    int age;
    float height;
    node *nxt;
};

int FillInLinkedList(node* temp)
{

int result;
temp = new node;

printf("Please enter name of the person");
result = scanf_s("%s", temp->name);

printf("Please enter persons age");
result = scanf_s("%d", &temp->age); // Exception here...

printf("Please enter persons height");
result = scanf_s("%f", &temp->height);

temp->nxt = NULL;
if (result >0)
    return  1;
 else return 0;
}

// calling code

int main(array<System::String ^> ^args)
{
  node temp;

  FillInLinkedList(&temp);

...

Ответы [ 5 ]

5 голосов
/ 28 февраля 2010

Вы используете scanf_s с неверными параметрами. Посмотрите на примеры в документации MSDN для этой функции. Это требует, чтобы вы передавали размер буфера после буфера для всех строковых или символьных параметров. Так

result = scanf_s("%s", temp->name); 

должно быть:

 result = scanf_s("%s", temp->name, 20);

Первый вызов scanf_s - это чтение мусора из стека, потому что он ищет другой параметр и, возможно, портит память.

Нет ошибки компилятора, потому что scanf_s использует список переменных аргументов - функция не имеет фиксированного количества параметров, поэтому компилятор не знает, что ожидает scanf_s.

3 голосов
/ 28 февраля 2010

Вам нужно

result = scanf_s("%d", &temp->age);

и

result = scanf_s("%f", &temp->height);

Причина в том, что sscanf (и друзьям) требуется указатель на выходную переменную, чтобы он мог сохранить результат там.

Кстати, у вас похожая проблема с параметром temp вашей функции. Поскольку вы меняете указатель (а не только содержимое того, на что он указывает), вам нужно передать двойной указатель, чтобы изменения были видны за пределами вашей функции:

int FillInLinkedList(node** temp)

И тогда, конечно, вам придется внести необходимые изменения в функцию.

2 голосов
/ 28 февраля 2010

scanf () сохраняет данные в переменных, поэтому вам нужно передать адрес переменной (или ее указатель)
Пример:

char string[10];
int n;
scanf("%s", string); //string actually points to address of
                     //first element of string array
scanf("%d", &n); // &n is the address of the variable 'n'
1 голос
/ 28 февраля 2010

Полагаю, вам нужно передать параметры в функции scanf () по адресу. т.е. & temp-> age

в противном случае temp-age будет интерпретироваться как указатель, что, скорее всего, приведет к краху вашей программы.

1 голос
/ 28 февраля 2010
  • %19c должно быть %s

  • temp->age должно быть &temp-age

  • temp->height должно быть &temp->height

  • Ваш компилятор должен предупреждать вас об этих ошибках

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