另一个函数中带有数组的双指针

Double pointer with array in another function

我必须创建一个程序,其中包含一个客户数组(包含名称、代码和文档的结构)和函数,用于按代码顺序插入、删除和列出所有这些客户。我不明白我应该做什么。请注意 insertCostumerremoveCostumerlistCostumer 的参数无法更改。

代码01:

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

#define MAX_REG 10

typedef struct _costumer {
    int code;
    char name[50];
    char documentation[20];
} costumer;

代码02:

int main(int argc, char** argv) {
    costumer *costumers[MAX_REG];
    costumer **p_costumer;
    p_costumer = &costumers[0];
    int count = 0;

    memset(costumers, 0, sizeof(costumers));

    //Some code to check what to do using a switch
            case '1': insertCostumer(p_costumer, &count); getch(); break;
            case '2': removeCostumer(p_costumer, &count); getch(); break;
            case '3': listCostumers(p_costumer, &count); getch(); break;
    //Some code
    return (EXIT_SUCCESS);
}

代码03:

void insertCostumer(costumer **p_costumer, int *count){
    char aux[50];
    char aux2[20];

    if(*count < MAX_REG) {
      *p_costumer = (costumer *) malloc(sizeof(costumer));
      printf("\nInsert the code: ");
      gets(aux);
      (*p_costumer)->code = atoi(aux);

      printf("Insert the name: ");
      gets(aux);
      strcpy((*p_costumer)->name, aux);

      printf("Insert the documentation: ");
      gets(aux2);
      strcpy((*p_costumer)->documentation, aux2);

      (*count)++;
      p_costumer = &*p_costumer[*count];

    } else {
        printf("List full! Remove a costumer first!\n");
    }
}

void removeCostumer(costumer **p_costumer, int *count){
    char aux3[50];
    int cod;

    printf("\nInsert the code of the costumer to be removed: ");
    gets(aux3);
    cod = atoi(aux3);

    for(int i = 0; i < *count; i++) {
        if(p_costumer[i]->code == cod) {
            strcpy(p_costumer[i]->name, NULL);
            p_costumer[i]->code = 0;
            strcpy(p_costumer[i]->documentation, NULL);
        }
      }
}

void listCostumers(costumer **p_costumer, int *count){
    for(int i = 0; i < *count; i++) {
        printf("Code: %d | Name: %s | Documentation: %s\n", p_costumer[i]->code, p_costumer[i]->name, p_costumer[i]->documentation);
    }
}

我不知道我做错了什么;老实说,没有任何效果。我试图先插入、列​​出和删除以尝试稍后进行排序部分,但我什至无法完成这部分。例如,我列出时,仅列出最后添加的客户。

有人可以帮助我吗?

好的,我不得不重构相当多的代码,所以我没有对更改的逐项描述。

你稍微研究一下就可以了。

请注意,即使您将双指针作为参数传递给您,也不意味着您必须将其用作函数主体中的双精度指针。请特别注意我为计数所做的工作(例如 int count = *p_count;*p_count = count;

但是,应该注意 list 是指向结构的 pointers 之一,not 只是一个指向结构数组的指针(即 一个额外的间接级别)。这让事情变得更快。

注意,bug修复不谈,关键是remove函数中的"slide"操作

因为我们是 "sliding" 指针,所以使用指针数组 faster/more 效率很高。好好研究这个[概念]

从不 使用 gets--总是使用 fgets

我故意不发表评论。这将允许您在分析代码时添加它们。我发现这是理解[外国]代码库的一种强大技术。

无论如何,这是代码。我已经完成了一些基本测试,它似乎有效:

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

#define MAX_REG 10
char aux[1000];

typedef struct _costumer {
    int code;
    char name[50];
    char documentation[20];
} costumer;

void
lineget(char *buf,size_t buflen)
{
    char *cp;

    cp = fgets(buf,buflen,stdin);

    if (cp != NULL) {
        cp = strrchr(buf,'\n');
        if (cp != NULL)
            *cp = 0;
    }
}

void
insertCostumer(costumer **p_costumer, int *p_count)
{
    costumer *add;
    int count = *p_count;

    char aux2[20];

    if (count < MAX_REG) {
        add = malloc(sizeof(costumer));

        printf("\nInsert the code: ");
        lineget(aux,sizeof(aux));
        add->code = atoi(aux);

        printf("Insert the name: ");
        lineget(add->name,sizeof(add->name));

        printf("Insert the documentation: ");
        lineget(add->documentation,sizeof(add->documentation));

        p_costumer[count] = add;
        ++count;
    }
    else {
        printf("List full! Remove a costumer first!\n");
    }

    *p_count = count;
}

void
removeCostumer(costumer **p_costumer, int *p_count)
{
    int count = *p_count;
    int cod;
    int i;
    costumer *cur;

    printf("\nInsert the code of the costumer to be removed: ");
    fgets(aux,sizeof(aux),stdin);
    cod = atoi(aux);

    int slide = 0;
    for (i = 0; i < count; i++) {
        cur = p_costumer[i];
        if (cur->code == cod) {
            slide = 1;
            break;
        }
    }

    if (slide) {
        free(cur);
        --count;

        for (;  i < count;  ++i)
            p_costumer[i] = p_costumer[i + 1];

        p_costumer[count] = NULL;
    }

    *p_count = count;
}

void
listCostumers(costumer **p_costumer, int *p_count)
{
    costumer *cur;
    int count = *p_count;

    for (int i = 0; i < count; ++i, ++cur) {
        cur = p_costumer[i];
        printf("Code: %d | Name: %s | Documentation: %s\n",
            cur->code, cur->name, cur->documentation);
    }
}

int
main(int argc, char **argv)
{
    costumer *costumers[MAX_REG];
    costumer **p_costumer;
    char buf[100];

    p_costumer = &costumers[0];
    int count = 0;

    memset(costumers, 0, sizeof(costumers));
    setbuf(stdout,NULL);

    //Some code to check what to do using a switch
    while (1) {
        printf("operation to perform (1=insert, 2=remove, 3=print): ");
        char *cp = fgets(buf,sizeof(buf),stdin);
        if (cp == NULL)
            break;

        switch (cp[0]) {
        case '1':
            insertCostumer(p_costumer, &count);
            break;

        case '2':
            removeCostumer(p_costumer, &count);
            break;

        case '3':
            listCostumers(p_costumer, &count);
            break;
        }
    }

    return (EXIT_SUCCESS);
}