2016-03-01 4 views
-4

Для моего введения в класс программирования мы должны закодировать телефонную книгу на C, которая позволяет пользователям добавлять контакты, а также удалять и отображать их. Он также должен выделять и освобождать память по мере необходимости (я пытался это сделать, но я честно не знаю, что я делаю).Как добавить контакт в программу телефонной книги в C?

В любом случае, я не могу понять, как добавить контакт в телефонную книгу. До сих пор я вставил соответствующую часть программы. Он компилируется, но он падает каждый раз, когда я пытаюсь добавить контакт. Как только я это выясню, я думаю, что могу без проблем справиться с остальными функциями. Если бы кто-нибудь мог мне помочь, я бы очень признателен.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct entry { 
    char fname[20]; 
    char lname[20]; 
    char pnumber[20]; 
} entry; 

// function prototypes 
void addentry(int, entry*, char addfname[20], char addlname[20], char addpnumber[20]); 

main() { 
    int selection = 0; 
    int inputtest = 1; 
    int pnum = 0; // keeps track of number of contacts 

    char addfname[20] = { '\0' }; 
    char addlname[20] = { '\0' }; 
    char addpnumber[20] = { '\0' }; 

    entry *pcontacts; 
    pcontacts = (entry*)calloc(1, (sizeof(entry))); 

    if (pcontacts == NULL) { 
     printf("No memory is available."); 
     free(pcontacts); 
     return 0; 
    } 

    while (1) { 
     do { 
      printf("\nPhonebook Menu\n\n"); 
      printf("1:\tAdd contact\n"); 
      printf("2:\tDelete contact\n"); 
      printf("3:\tDisplay contacts\n"); 
      printf("4:\tExit\n"); 
      printf("\nChoose an action (1-4): "); 
      scanf("%d", &selection); 

      if (selection < 1 || selection > 4) { 
       printf("Invalid input. Please enter an integer between 1 and 4.\n"); 
       inputtest = 0; 
      } 
      if (selection == 4) { 
       free(pcontacts); 
       printf("\nThank you for using this phonebook."); 
       return 0; 
      } 
      switch (selection) { 
       case 1: 
       pnum++; 
       printf("\nEnter first name: "); 
       scanf("%s", addfname); 
       printf("Enter last name: "); 
       scanf("%s", addlname); 
       printf("Enter phone number (no spaces): "); 
       scanf("%s", addpnumber); 
       addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]); 
       break; 
      } 
     } while (inputtest == 1); 
    } 
} 

void addentry(int pnum, entry *pcontacts, char addfname[20], char addlname[20], char pnumber[20]) { 

    pcontacts = (entry*)malloc(pnum * (sizeof(entry))); 

    if (pcontacts != NULL) { 
     strcpy(*pcontacts[pnum - 1].fname, addfname); 
     printf("\nContact has been added."); 
    } else { 
     printf ("No memory is available.\n"); 
    } 
} 
+0

использовать отладчик, чтобы выяснить, где происходит сбой. –

+1

В функции C аргументы передаются по значению. Итак, 'pcontacts = (entry *) malloc (pnum * (sizeof (entry)));' только устанавливает локальную переменную * и теряется, как только функция завершается. То есть, эта функция в действительности является большим noop. И нет смысла выделять записи 'pnum', заполнять последнюю запись, а затем оставлять все остальное до ее неинициализации. Очевидно, вам нужно * добавить * к существующей структуре списка/массива/данных, а не делать то, что вы делаете. – kaylum

+0

'strcpy (* pcontacts [pnum-1] .fname, addfname);'. Это линия, которая может привести к вашему краху (кроме функционального неправильного, как описано выше). Это должно быть 'strcpy (pcontacts [pnum-1] .fname, addfname);' – kaylum

ответ

1

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

scanf("%19s", addfname); 
... 
scanf("%19s", addlname); 
... 
scanf("%19s", addpnumber); 

способ вызова addentry является неправильно:

addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]); 

Вы на самом деле попытаться прочитать байты только после окончания addfname, addlname и addpnumber. Вместо этого вы должны пройти сами массивы, которые будут переданы функциями addentry в качестве указателей на свои первые байты:

addentry(pnum, pcontacts, addfname, addlname, addpnumber); 

addentry должен перераспределить массив с realloc. Он должен быть передан указателю на указатель массива, чтобы он мог обновить указатель в main.

addentry не копирует строки правильно: он копирует только один, но с синтаксической ошибкой.

Вот исправленный вариант:

void addentry(int, entry**, char addfname[20], char addlname[20], char addpnumber[20]); 

int main(void) { 
    int selection = 0; 
    int inputtest = 1; 
    int pnum = 0; // keeps track of number of contacts 

    char addfname[20]; 
    char addlname[20]; 
    char addpnumber[20]; 

    entry *pcontacts = NULL; 

    for (;;) { 
     do { 
      printf("\nPhonebook Menu\n\n"); 
      printf("1:\tAdd contact\n"); 
      printf("2:\tDelete contact\n"); 
      printf("3:\tDisplay contacts\n"); 
      printf("4:\tExit\n"); 
      printf("\nChoose an action (1-4): "); 
      scanf("%d", &selection); 

      if (selection < 1 || selection > 4) { 
       printf("Invalid input. Please enter an integer between 1 and 4.\n"); 
       inputtest = 0; 
      } 
      if (selection == 4) { 
       free(pcontacts); /* OK for NULL */ 
       printf("\nThank you for using this phonebook."); 
       return 0; 
      } 
      switch (selection) { 
       case 1: 
       printf("\nEnter first name: "); 
       scanf("%19s", addfname); 
       printf("Enter last name: "); 
       scanf("%19s", addlname); 
       printf("Enter phone number (no spaces): "); 
       scanf("%19s", addpnumber); 
       addentry(pnum, &pcontacts, addfname, addlname, addpnumber); 
       pnum++; 
       break; 
      } 
     } while (inputtest == 1); 
    } 
} 

/* add an entry at position pnum */ 
void addentry(int pnum, entry **pp, char addfname[20], char addlname[20], char pnumber[20]) { 

    entry *pcontact = *pp; 
    pcontacts = realloc(pcontacts, (pnum + 1) * sizeof(entry)); 

    if (pcontacts != NULL) { 
     *pp = pcontacts; /* update pointer in main */ 
     strcpy(pcontacts[pnum].fname, addfname); 
     strcpy(pcontacts[pnum].lname, addlname); 
     strcpy(pcontacts[pnum].pnumber, addpnumber); 
     printf("\nContact has been added."); 
    } else { 
     printf ("No memory is available.\n"); 
    } 
} 
Смежные вопросы