在c中打印出我的结构数组时遇到问题

问题描述 投票:3回答:3

我目前在课堂上的项目是制作一个程序,作为使用结构的电话簿。我已经编写了“添加联系人”功能和“显示联系人”功能,但是当我有多个联系人时,“显示联系人”功能会显示最近一次联系人所期望的所有联系人的乱码。任何人都可以帮我找到问题吗?

这是我目前的代码。如果有什么问题让我知道,我会尽快回复。

#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
c struct
3个回答
3
投票

您的代码存在一些问题:

1>变量a,b,con的范围应该在main函数中,通过在case块代码中重新声明它们,从主函数范围到in-case范围覆盖变量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指针

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;
}

1
投票

你在con语句中定义了一个名为switch的新变量。此变量将屏蔽在函数顶部定义的同名变量。这是你要添加记录的那个。

当你以后去打印列表时,它实际上是从这个内部con读取。但是,由于您正在重新输入switch语句,因此变量的内容未初始化,因为您因为切换而跳过初始化程序并调用undefined behavior。你很幸运能够打印读入的最后一个实例,可能是因为变量仍然包含上一次迭代的旧值。

此外,con的外部版本被声明为指针数组。您可能只需要一个指针,这样它就可以指向一个动态分配的数组。

所以定义con像这样:

struct contact *con = NULL;

并更改“添加”案例以不定义变量。此外,您不需要单独的变量来读取值。您可以直接将它们读入结构的实例:

            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++){

1
投票

正如@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 page,或在终端上输入man 3 reallocman realloc

编辑@dbush建议

您声明了2个名为con的变量。在开始struct contact *con[200];和switch语句中,您分配内存并将其保存到struct concat *con

所以你仍然得到选项“3”(显示所有联系人)的未定义结果的原因是,你实际上是从数组struct contact *con[200];读取联系人而不是从struct contact *con;指向的内存中读取联系人

问候

© www.soinside.com 2019 - 2024. All rights reserved.