使用带结构的C创建地址簿

时间:2014-10-24 18:16:47

标签: c

我的目的是使用C的结构创建一个包含10个联系人的地址簿。用户必须逐个插入联系人,我的程序应该打印整个地址簿。编译成功但是当我运行我的程序时,它只打印第一个联系人,然后我得到分段错误。这是我的代码:

文件Ex7.h:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define DIM 10

struct person {
    char name[40];
    char surname[40];
    char date[11];
    char number[11];
};

typedef struct person Person;

void dataEntry(Person *person);
void printPerson(Person person);
void printAddressBook(Person *addbook[10]);

文件Ex7.c:

#include "ex7.h"

void dataEntry(Person *person) {
    printf("Insert name: ");
    gets(person -> name);
    printf("Insert surname: ");
    gets(person -> surname);
    printf("Insert date of birth [mm/dd/yyyy]: ");
    gets(person -> date);
    printf("Insert phone number: ");
    gets(person -> number);
}



void printPerson(Person person) {
    printf("Name: %s\n", person.name);
    printf("Surname: %s\n", person.surname);
    printf("Date of birth: %s\n", person.date);
    printf("Number: %s\n\n", person.number);
}



void printAddressBook(Person *addbook[10]) {
    for (int i = 0; i < DIM; i++) {
        printPerson(*addbook[i]);
    }
}

文件main.c:

#include "ex7.h"

int main(void) {
    Person* addbook = (Person*) malloc(DIM*sizeof(Person));
    printf("DATA ENTRY\n\n");
    for (int i = 0; i < DIM; i++) {
        printf("Person %d:\n", i);
        dataEntry(&addbook[i]);
    }
    printf("\n\nPRINTING ADDRESS BOOK...\n\n");
    printAddressBook(&addbook);
    return 0;
}

然后我编译了所有输入的内容:gcc -o main main.c ex7.c -std = c99

2 个答案:

答案 0 :(得分:2)

问题出在这一部分:

void printAddressBook(Person *addbook[10]) {
    for (int i = 0; i < DIM; i++) {
        printPerson(*addbook[i]);
    }
}

该方法需要一个人指针数组,在main中你传递一个指向persons数组的指针,而不是你分配的person数组。 所以将方法改为:

void printAddressBook(Person *addbook) {
    for (int i = 0; i < DIM; i++) {
        printPerson(addbook[i]);
    }
}

主要是这样说:

printAddressBook(addbook);

答案 1 :(得分:0)

首先不要使用获取。它已被弃用,不再是当前标准的一部分。 fgets工作正常。您必须始终如一地将指向结构集的指针传递给每个函数。另外,以这种方式使用malloc会引起valgrind Conditional jump or move depends on uninitialised value(s)的投诉。您可以使用calloc进行分配,以确保所有数据都已初始化为NULL。纠正这些问题的一种方法如下。使用getline提供了一个新的输入例程来获取输入而不是'gets':

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

#define DIM 10

struct person {
    char name[40];
    char surname[40];
    char date[11];
    char number[11];
};

typedef struct person Person;

void dataEntry(Person *person);
void printPerson(Person *person);
void printAddressBook(Person *addbook);

int main(void) {
    Person* addbook = calloc (DIM, sizeof(Person)); /* calloc initializes all storage */
    printf("DATA ENTRY\n\n");
    for (int i = 0; i < DIM; i++) {
        printf("Person %d:\n", i);
        dataEntry(&addbook[i]);
    }
    printf("\n\nPRINTING ADDRESS BOOK...\n\n");
    printAddressBook(addbook);
    if (addbook) free (addbook);
    return 0;
}

/* get string input using getline and write to 'string' */
void getinput (char *string)
{
    ssize_t read = 0;                   /* values to use with getline       */
    char *line = NULL;                  /* forces getline to allocate mem   */
    size_t n = 0;                       /* bytes to read, 0 no-limit        */
    read = getline (&line, &n, stdin);  /* read from stdin with getline     */
    if (line[read - 1] == '\n')         /* if newline at end of line        */
        { line[read - 1] = 0; read--; } /* strip newline                    */
    strncpy (string, line, read);       /* copy line w/o linefeed to string */
    if (line) free (line);              /* free memory allocated by getline */
}

void dataEntry(Person *person) {
    printf("Insert name: ");
    getinput (person -> name);
    printf("Insert surname: ");
    getinput (person -> surname);
    printf("Insert date of birth [mm/dd/yyyy]: ");
    getinput (person -> date);
    printf("Insert phone number: ");
    getinput (person -> number);
}

void printPerson(Person *person) {
    printf("Name    : %s\n", person -> name);
    printf("Surname : %s\n", person -> surname);
    printf("D.O.B.  : %s\n", person -> date);
    printf("Number  : %s\n\n", person -> number);
}

void printAddressBook(Person *addbook) {
    for (int i = 0; i < DIM; i++) {
        printPerson(&addbook[i]);
    }
}

另外,不要忘记释放最后分配的内存。

<强>输出:

$ ./bin/abook
DATA ENTRY

Person 0:
Insert name: dog
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 12/12/1912
Insert phone number: 555-1212
Person 1:
Insert name: cat
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 11/11/1911
Insert phone number: 555-1212
Person 2:
Insert name: rat
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 10/10/1910
Insert phone number: 555-1212
Person 3:
Insert name: flat
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 09/09/1909
Insert phone number: 555-1212
Person 4:
Insert name: fat
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 08/08/1908
Insert phone number: 555-1212
Person 5:
Insert name: bat
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 07/07/1907
Insert phone number: 555-1212
Person 6:
Insert name: hat
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 06/06/1906
Insert phone number: 555-1212
Person 7:
Insert name: Matt
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 05/05/1905
Insert phone number: 555-1212
Person 8:
Insert name: george
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 04/04/1904
Insert phone number: 555-1212
Person 9:
Insert name: harry
Insert surname: fish
Insert date of birth [mm/dd/yyyy]: 03/03/1903
Insert phone number: 555-1212


PRINTING ADDRESS BOOK...

Name: dog
Surname: fish
Date of birth: 12/12/1912
Number: 555-1212

Name: cat
Surname: fish
Date of birth: 11/11/1911
Number: 555-1212

Name: rat
Surname: fish
Date of birth: 10/10/1910
Number: 555-1212

Name: flat
Surname: fish
Date of birth: 09/09/1909
Number: 555-1212

Name: fat
Surname: fish
Date of birth: 08/08/1908
Number: 555-1212

Name: bat
Surname: fish
Date of birth: 07/07/1907
Number: 555-1212

Name: hat
Surname: fish
Date of birth: 06/06/1906
Number: 555-1212

Name: Matt
Surname: fish
Date of birth: 05/05/1905
Number: 555-1212

Name: george
Surname: fish
Date of birth: 04/04/1904
Number: 555-1212

Name: harry
Surname: fish
Date of birth: 03/03/1903
Number: 555-1212