Возникли проблемы при печати моего массива структуры в c - PullRequest
0 голосов
/ 13 февраля 2019

Мой текущий проект в классе - создать программу, которая работает как телефонная книга с использованием структур.Я закодировал функцию «добавить контакты» и функцию «показать контакты», но когда у меня есть более одного контакта, функция «показать контакты» показывает бред для всех контактов, ожидаемых для самого последнего.Кто-нибудь может помочь мне найти проблему?

Вот мой текущий код.Если что-то сбивает с толку, дайте мне знать, и я постараюсь ответить как можно быстрее.

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

struct contact {                // Data structure that holds contact information 
    char FirstName[10];         // Array for first name
    char LastName[10];          // Array for last name
    int PhoneNum;               // Phone number
};

int main (){

    // Setting up variables
    int Function = 0;
    int Choice = 0;
    char FName[200][10];
    char LName[200][10];
    int PNum = 0;
    int n = 1;
    struct contact *con[200];
    int b = 0;

    do{     // Will loop through the main function until the user decides to exit the program

        // Prints out the main menu of the phone book
        printf("\nPhone Book");
        printf("\n[1] Add a contact");
        printf("\n[2] Delete a contact");
        printf("\n[3] Show contacts");
        printf("\n[4] Exit program");
        printf("\n\nWhat function would you like to use?\n");       // Asks for user input
        scanf("%d", &Choice);

        switch(Choice){
            case 1:     // Case to add a contact into the phone book
                printf("\nYou chose to add a contact.");
                printf("\nFirst name: ");
                scanf("%s", &FName[b]);
                printf("\nLast name: ");
                scanf("%s", &LName[b]);
                printf("\nPhone number (Numbers only): ");
                scanf("%d", &PNum);
                printf("\nRecord added to the phone book");

                // Records the information given into the structure
                struct contact *con = (struct contact*)malloc(n*sizeof(struct contact));
                int a = (n - 1);

                printf("\na is %d", a);

                strcpy(con[a].FirstName, FName[b]);
                strcpy(con[a].LastName, LName[b]);
                con[a].PhoneNum = PNum;

                int b = (b+1);
                n++;

                printf("\nn is %d", n);

                // Prints out the given information
                printf("\nNew contact:");
                printf("\nFirst name: %s", con[a].FirstName);
                printf("\nLast name: %s", con[a].LastName);
                printf("\nPhone number: %d", con[a].PhoneNum);  
                printf("\n");
                break;
            case 2:     // Case to delete a contact from the phone book
                printf("\nYou chose to delete a contact.");
                break;
            case 3:     // Case to see all of the entered contacts
                printf("\nYou chose to show the contacts.");
                for(a = 0; a < (n - 1); a++){
                    printf("\nContact #%d", a);
                    printf("\nFirst name: %s", con[a].FirstName);
                    printf("\nLast name: %s", con[a].LastName);
                    printf("\nPhone number: %d", con[a].PhoneNum);  
                    printf("\n");               
                }
                break;
            case 4:
                printf("Goodbye!");
                break;
        }
    }while (Choice != 4);
    return 0;   
}

Это вывод, который я получаю, когда запускаю свой код.

Phone Book
[1] Add a contact
[2] Delete a contact
[3] Show contacts
[4] Exit program

What function would you like to use?
1

You chose to add a contact.
First name: Test

Last name: 1

Phone number (Numbers only): 1234567

Record added to the phone book
a is 0
n is 2
New contact:
First name: Test
Last name: 1
Phone number: 1234567

Phone Book
[1] Add a contact
[2] Delete a contact
[3] Show contacts
[4] Exit program

What function would you like to use?
1

You chose to add a contact.
First name: test

Last name: 2

Phone number (Numbers only): 8901234

Record added to the phone book
a is 1
n is 3
New contact:
First name: test
Last name: 2
Phone number: 8901234

Phone Book
[1] Add a contact
[2] Delete a contact
[3] Show contacts
[4] Exit program

What function would you like to use?
3

You chose to show the contacts.
Contact #0
First name: Pq
Last name: q
Phone number: 1095516483

Contact #1
First name: test
Last name: 2
Phone number: 8901234

Ответы [ 3 ]

0 голосов
/ 13 февраля 2019

Вы определяете новую переменную с именем con внутри вашего оператора switch.Эта переменная mask переменная с тем же именем, определенная в верхней части функции.Это та запись, к которой вы добавляете запись.

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

Кроме того, внешняя версия conобъявлен как массив указателей .Возможно, вам нужен только указатель, чтобы он мог указывать на динамически размещенный массив.

Итак, определите con следующим образом:

struct contact *con = NULL;

И измените регистр «add», чтобы он не определялсяпеременная.Кроме того, вам не нужны отдельные переменные для чтения значений.Вы можете прочитать их непосредственно в экземпляре структуры:

            n++;
            con = realloc(n*sizeof(struct contact));

            printf("\nYou chose to add a contact.");
            printf("\nFirst name: ");
            scanf("%s", con[n-1].FirstName);
            printf("\nLast name: ");
            scanf("%s", con[n-1].LastName);
            printf("\nPhone number (Numbers only): ");
            scanf("%d", &con[n-1].PhoneNum );
            printf("\nRecord added to the phone book");

            printf("\nn is %d", n);

            printf("\nNew contact:");
            printf("\nFirst name: %s", con[n-1].FirstName);
            printf("\nLast name: %s", con[n-1].LastName);
            printf("\nPhone number: %d", con[n-1].PhoneNum);  
            printf("\n");

Затем вам также нужно переместиться на a вниз к части "show":

for( int a = 0; a < (n - 1); a++){
0 голосов
/ 13 февраля 2019

В вашем коде есть некоторые проблемы:

1> Область действия переменной a, b, con должна быть в главной функции, вы переопределяете область видимости переменной a, b из области основной функции вобъем дела путем повторного объявления их внутри кода блока дела.

int b = b+1;
int a = (n-1);
struct contact *con = (struct contact*)malloc(n*sizeof(struct contact));

В случае кода блока, просто присвойте им новое значение:

b = b+1;
a = (n-1);
con = (struct contact*)malloc(n*sizeof(struct contact));   

2> con *Указатель 1010 * должен быть изменен с

struct contact *con[200];

путем определения для него инициализированного размера.и если размер выходит за пределы диапазона, нам нужно перераспределить con в случае добавления нового элемента:

int size = 200;
struct contact *con = (struct contact *)malloc(size * sizeof(struct contact));

// in case of the size of out of range
if (n >= size)
{
   size = size * 2;
   con = (struct contact*)realloc(con, size * sizeof(struct contact));
}

Вот мое решение:

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

struct contact {                // Data structure that holds contact information 
    char FirstName[10];         // Array for first name
    char LastName[10];          // Array for last name
    int PhoneNum;               // Phone number
};

int main() {

    // Setting up variables
    int Function = 0;
    int Choice = 0;
    char FName[200][10];
    char LName[200][10];
    int PNum = 0;
    int n = 1;
    int size = 200;
    struct contact *con = (struct contact *)malloc(size * sizeof(struct contact));
    int b = 0, a = 0;

    do {     // Will loop through the main function until the user decides to exit the program

        // Prints out the main menu of the phone book
        printf("\nPhone Book");
        printf("\n[1] Add a contact");
        printf("\n[2] Delete a contact");
        printf("\n[3] Show contacts");
        printf("\n[4] Exit program");
        printf("\n\nWhat function would you like to use?\n");       // Asks for user input
        scanf("%d", &Choice);

        switch (Choice) {
        case 1:     // Case to add a contact into the phone book
            printf("\nYou chose to add a contact.");
            printf("\nFirst name: ");
            scanf("%s", &FName[b]);
            printf("\nLast name: ");
            scanf("%s", &LName[b]);
            printf("\nPhone number (Numbers only): ");
            scanf("%d", &PNum);
            printf("\nRecord added to the phone book");

            // Records the information given into the structure
            if (n >= size)
            {
                size = size * 2;
                con = (struct contact*)realloc(con, size * sizeof(struct contact));
            }
            a = (n - 1);

            printf("\na is %d", a);

            strcpy(con[a].FirstName, FName[b]);
            strcpy(con[a].LastName, LName[b]);
            con[a].PhoneNum = PNum;

            b = (b + 1);
            n++;

            printf("\nn is %d", n);

            // Prints out the given information
            printf("\nNew contact:");
            printf("\nFirst name: %s", con[a].FirstName);
            printf("\nLast name: %s", con[a].LastName);
            printf("\nPhone number: %d", con[a].PhoneNum);
            printf("\n");
            break;
        case 2:     // Case to delete a contact from the phone book
            printf("\nYou chose to delete a contact.");
            break;
        case 3:     // Case to see all of the entered contacts
            printf("\nYou chose to show the contacts.");
            for (a = 0; a < (n - 1); a++) {
                printf("\nContact #%d", a);
                printf("\nFirst name: %s", con[a].FirstName);
                printf("\nLast name: %s", con[a].LastName);
                printf("\nPhone number: %d", con[a].PhoneNum);
                printf("\n");
            }
            break;
        case 4:
            printf("Goodbye!");
            break;
        }
    } while (Choice != 4);
    return 0;
}
0 голосов
/ 13 февраля 2019

Как заметил программист @Some, вам нужно перераспределить массив, если вы хотите увеличить его и сохранить данные.

Таким образом, что-то вроде этого

// Records the information given into the structure
   struct contact *con = (struct contact*)malloc(n*sizeof(struct contact));

должно быть вначало вашей main функции выглядит следующим образом:

// dynamically allocate memory which can hold e.g. 1 struct
struct contact *con = malloc(sizeof(struct contact));

, и когда вы изменяете размер своего куска памяти в куче, это то, что malloc делает для вас, вы должны изменить размер или realloc следующим образом:

// grow array 
con = realloc(con, n * sizeof(struct concat));

Прочтите справочную страницу для получения дополнительной информации: Справочная страница realloc или введите man 3 realloc или man realloc на своем терминале.

РЕДАКТИРОВАТЬ Как предложил @dbush

Вы объявляете 2 переменные с именем con.В начале struct contact *con[200]; и в операторе switch вы выделяете память и сохраняете ее в struct concat *con.

Таким образом, причина, по которой вы по-прежнему получаете неопределенные результаты для опции "3" (показать все контакты), заключается в том, что вы на самом деле читаете контакты из массива struct contact *con[200];, а не из памяти, указанной struct contact *con;

Привет

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