当我介绍 1 名或更多患者时,如何阻止我的患者数据重叠或从其他地方获取随机数据 [已关闭]

问题描述 投票:0回答:1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    int id[100];
    char name[100][50], insurance[100][20];
    int choice, age[100], hasInsurance, x=0, y=0, z, position, temp;
    char continueInput;
     
    do {
        printf("1.- Register \n");
        printf("2.- Consult \n");
        printf("3.- Exit \n");
        scanf("%d", &choice);
         
        switch(choice) {
            case 1:
                do {
                    printf("\nEnter patient's name: ");
                    scanf("%s", name[x]);
                    fflush(stdin);
                    printf("\nEnter patient's ID: ");
                    scanf("%i", &id[x]);
                    fflush(stdin);
                    printf("\nEnter patient's age: ");
                    scanf("%i", &age[x]);
                    fflush(stdin);
                    printf("\nEnter 1 if the patient has medical insurance or 0 if not: ");
                    scanf("%i", &hasInsurance);
                    fflush(stdin);
                    if (hasInsurance != 0) {
                        printf("Name of the insurance company: ");
                        scanf("%s", insurance[x]);
                        fflush(stdin);
                    }
                    x++;
                    printf("\nDo you want to continue entering patients? (y/n): ");
                    scanf(" %c", &continueInput);
                    fflush(stdin);
                } while(continueInput != 'n' && x < 100);
                break;
                
            case 2:
                do {
                    printf("\n4.- General \n");
                    printf("5.- Elderly Patients \n");
                    printf("6.- Return to Main Menu \n");
                    scanf("%d", &choice);
                    switch (choice) {
                        case 4:
                            for(z = 0; z < x; z++) {  
                                printf("\nID: %i Name: %s Age: %i Insurance: %s - Patient has insurance \n", id[z], name[z], age[z], insurance[z]);
                                if (hasInsurance == 0) {
                                    printf("\nID: %i Name: %s Age: %i  - Patient does not have insurance \n", id[z], name[z], age[z]); 
                                }
                            }
                            break;
                        case 5:
                            for(z = 0; z < x; z++) {
                                if (age[z] >= 60) {
                                    printf("\nName: %s Age: %i \n", name[z], age[z]);
                                } else {
                                    printf("No information available.\n");
                                }
                            }
                            break;
                    }
                } while (choice != 6);
                break;
        }
    } while (choice != 3);
    
    return 0; 
}

我对出院中的一般咨询部分感到困惑。我已经这样做了一个小时了。当我打印入院病人时,如果我只输入一名,所输入数据的打印是无可挑剔的,但当再输入1名时,以及ID AGE和是否投保的情况时,他们会发疯,使用随机数据/或相同的数据,但从最近输入的数据覆盖/重叠。在附图中,我向两名入院患者展示了我的语法和程序

我有一个理论,我必须使用患者作为变量?这就是为什么当输入超过 1 时数据会被覆盖吗?我也有这样的理论:我的周期是错误的,我必须使用超过 1 个变量来解决保险问题,这就是为什么像 truefalse 这样的东西会起作用,基本上是一个 if 但转换为一个变量。

c algorithm
1个回答
-2
投票

在下面的TL:DR,我将发布一个编写此类代码的可能方法的示例。这是一篇又长又无聊的文章,因为我正在编码

如果你的老师说

fflush
是必需的 --- 并且建议使用 Dev C++ 作为 IDE --- 我对此感到抱歉。也许也是因为你的老师,你的代码还有很多其他问题。

  • fflush
    没有为输入流定义。无论如何,没什么意义。不要使用它。
  • 这是您的数据:
    int  id[100];
    char name[100][50], insurance[100][20];
    int  choice, age[100], hasInsurance, x = 0, y = 0, z,
                                        position, temp;
    char continueInput;

这不好。

  • 您有一个患者数据容器,但它不在您的代码中:只是包含患者数据的数组分布在代码中。只要您对数据的表示与真实数据不同,编写代码来处理它就会更加困难。并且将患者数量命名为
    x
    也没有帮助。
  • 这很有趣:
        printf("1.- Register \n");
        printf("2.- Consult \n");
        printf("3.- Exit \n");
        scanf("%d", &choice);

为什么要打 3 次电话给

printf
?您的老师知道(并告诉您)
scanf
是扫描仪吗?它返回一个
int
?你应该测试它,因为对于扫描仪来说什么也不读取不是错误?

如果它是一个菜单,为什么不使用如此命名的函数来显示选项并返回用户的选择?

  • 每行不要使用多个声明。线路免费。
  • 初始化所有变量。

为什么代码失败?

您需要一种方法来识别在数组中是否有患者有保险。 A

0
作为 1s 字符就可以了,如

    if (hasInsurance != 0)
    {
        printf(
            "Name of the insurance "
            "company: ");
        scanf("%s", insurance[x]);
        fflush(stdin);
    }
    else
        insurance[x][0] = 0;

这样,当需要打印时,您就有办法对其进行测试,如

    for (z = 0; z < x; z++)
    {
        if (insurance[z][0] != 0)
        printf(
            "\nID: %i Name: %s "
            "Age: %i - Insurance company is: %s\n",
            id[z], name[z], age[z],
            insurance[z]);
        else
        {
            printf(
                "\nID: %i Name: %s "
                "Age: %i  - "
                "Patient does not "
                "have insurance\n",
                id[z], name[z],
                age[z]);
        }
    }
  • x
    因为病人数量实在是一个糟糕的选择。

定义数据:封装

考虑一下您的数据可以被视为这样

#define MAX_PATIENTS 100
#define ELDERLY_AGE 60
#define OPT_ADD '1'
#define OPT_LIST_ALL '2'
#define OPT_LIST_ELDERLY '3'
#define OPT_EXIT '4'

typedef struct
{
    unsigned id;
    unsigned age;
    char     name[50];
    char     insurance[20];
} Patient;

typedef struct
{
    unsigned limit;
    unsigned size;
    unsigned elderly;
    Patient  p[MAX_PATIENTS];
} Patients;

想想你的代码可以变得多么简单:

Patients
Patient
容器
。这称为封装,是一个强大的概念。

TL:博士

围绕这些数据书写:函数

// show a patient with optional message
int so_show_one(Patient* p, const char* msg);
// show all patients, with optional message
// 'opt' is used to signal filtering for elderly
// patients
int so_show(Patients* p, char opt, const char* msg);
// prints menu, returns option. pass patients struct just to
// show total on menu
char so_menu(Patients* set);
// insert a patient into a group
int so_insert(Patient* p, Patients* set);
// returns a new patient, factory function
Patient so_factory(void);

使用中的操作就是这些了。

  • 封装使代码只能处理本地数据。
  • menu()
    返回用户选项。按 ENTER 两次退出程序:更快的测试。
  • so_factory()
    在每次调用时都会生成完整的
    Patient
    。无需浪费时间输入数据进行测试。年龄和保险状况是随机设置的。
  • so_show()
    列出所有患者,但使用委托并调用
    so_show_one()
    来打印每个
    Patient
    :更容易测试、更改和维护。
  • srand()
    使用已知种子,为每个测试重复数据

main()
用于示例测试

int main(void)
{
  srand(240421);
  Patients my_test = {
      .limit = MAX_PATIENTS, .size = 0, .elderly = 0};
  Patient one    = {0};
  char    choice = 0;
  do {
      choice = so_menu(&my_test);
      switch (choice)
      {
          case OPT_ADD:
              one = so_factory();  // get a patient
              so_insert(&one, &my_test);
              break;
          case OPT_LIST_ALL:
              so_show(&my_test, 0, "\n[ALL patients]  ");
              break;
          case OPT_LIST_ELDERLY:
              so_show(
                  &my_test, ELDERLY_AGE,
                  "\n[ELDERLY patients]  ");
              break;
          default:
              break;
      }
  } while (choice != OPT_EXIT);
  return 0;
}

示例输出

    Menu:

    1 - Register a new patient
    2 - List all 11 patients
    3 - List only 7 elderly Patients

    Press ENTER twice to exit:  2

[ALL patients]  11/100 Patients in this group:

  1  1000         Name XYZ1000, age 66 - Insurance: at 'Insurance 1000 Co.'
  2  1001         Name XYZ1001, age 55 - Insurance: at 'Insurance 1001 Co.'
  3  1002         Name XYZ1002, age 65 - Insurance: no
  4  1003         Name XYZ1003, age 38 - Insurance: no
  5  1004         Name XYZ1004, age 28 - Insurance: no
  6  1005         Name XYZ1005, age 89 - Insurance: at 'Insurance 1005 Co.'
  7  1006         Name XYZ1006, age 80 - Insurance: no
  8  1007         Name XYZ1007, age 71 - Insurance: at 'Insurance 1007 Co.'
  9  1008         Name XYZ1008, age 86 - Insurance: no
 10  1009         Name XYZ1009, age 47 - Insurance: no
 11  1010         Name XYZ1010, age 93 - Insurance: no


    Menu:

    1 - Register a new patient
    2 - List all 11 patients
    3 - List only 7 elderly Patients

    Press ENTER twice to exit:  3

[ELDERLY patients]  7/100 Patients in this group:

  1  1000         Name XYZ1000, age 66 - Insurance: at 'Insurance 1000 Co.'
  2  1002         Name XYZ1002, age 65 - Insurance: no
  3  1005         Name XYZ1005, age 89 - Insurance: at 'Insurance 1005 Co.'
  4  1006         Name XYZ1006, age 80 - Insurance: no
  5  1007         Name XYZ1007, age 71 - Insurance: at 'Insurance 1007 Co.'
  6  1008         Name XYZ1008, age 86 - Insurance: no
  7  1010         Name XYZ1010, age 93 - Insurance: no


    Menu:

    1 - Register a new patient
    2 - List all 11 patients
    3 - List only 7 elderly Patients

    Press ENTER twice to exit:

示例的完整代码

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

#define MAX_PATIENTS 100
#define ELDERLY_AGE 60
#define OPT_ADD '1'
#define OPT_LIST_ALL '2'
#define OPT_LIST_ELDERLY '3'
#define OPT_EXIT '4'

typedef struct
{
    unsigned id;
    unsigned age;
    char     name[50];
    char     insurance[20];
} Patient;

typedef struct
{
    unsigned limit;
    unsigned size;
    unsigned elderly;
    Patient  p[MAX_PATIENTS];
} Patients;

// show a patient with optional message
int so_show_one(Patient* p, const char* msg);
// show all patients, with optional message
// 'opt' is used to signal filtering for elderly
// patients
int so_show(Patients* p, char opt, const char* msg);
// prints menu, returns option. pass patients struct just to
// show total on menu
char so_menu(Patients* set);
// insert a patient into a group
int so_insert(Patient* p, Patients* set);
// returns a new patient, factory function
Patient so_factory(void);

int main(void)
{
    srand(240421);
    Patients my_test = {
        .limit = MAX_PATIENTS, .size = 0, .elderly = 0};
    Patient one    = {0};
    char    choice = 0;
    do {
        choice = so_menu(&my_test);
        switch (choice)
        {
            case OPT_ADD:
                one = so_factory();  // get a patient
                so_insert(&one, &my_test);
                break;
            case OPT_LIST_ALL:
                so_show(&my_test, 0, "\n[ALL patients]  ");
                break;
            case OPT_LIST_ELDERLY:
                so_show(
                    &my_test, ELDERLY_AGE,
                    "\n[ELDERLY patients]  ");
                break;
            default:
                break;
        }
    } while (choice != OPT_EXIT);
    return 0;
}

int so_show_one(Patient* p, const char* msg)
{
    if (p == NULL) return -1;
    if (msg != NULL) printf("%s", msg);
    if (p->insurance[0] == 0)
        printf(
            "%6i %20s, age %2i - Insurance: no\n", p->id,
            p->name, p->age);
    else
        printf(
            "%6i %20s, age %2i - Insurance: at '%s'\n", p->id,
            p->name, p->age, p->insurance);
    return 0;
}

int so_show(Patients* set, char opt, const char* msg)
{
    if (set == NULL) return -1;
    unsigned size = set->size;
    if (opt == ELDERLY_AGE) size = set->elderly;
    if (msg != NULL)
        printf(
            "%s%u/%u Patients in this group:\n\n", msg, size,
            set->limit);
    else
        printf(
            "%u/%u Patients in tis group:\n\n", size,
            set->limit);
    char   seq[6] = {0};
    size_t pos    = 0;
    for (size_t i = 0; i < set->size; i += 1)
    {  // uses msg field to print sequence number
        if (opt == ELDERLY_AGE)
        {
            if (set->p[i].age >= ELDERLY_AGE)
            {
                sprintf(seq, "%3llu", 1 + pos);
                so_show_one(&(set->p[i]), seq);
                pos += 1;
            }
        }
        else
        {
            sprintf(seq, "%3llu", 1 + pos);
            so_show_one(&(set->p[i]), seq);
            pos += 1;
        }
    }
    printf("\n");
    return 0;
}

char so_menu(Patients* set)
{
    int  try = 0;
    char line[80];
    if (set == NULL) return OPT_EXIT;
    do {
        printf(
            "\n\
    Menu:\n\
\n\
    1 - Register a new patient\n\
    2 - List all %u patients\n\
    3 - List only %u elderly Patients\n\
\n\
    Press ENTER twice to exit:  ",
            set->size, set->elderly);
        char* p = fgets(line, sizeof(line), stdin);
        if (p == NULL) return OPT_EXIT;
        if (*p == '\n') ++try;
        if (line[0] < OPT_ADD) continue;
        if (line[0] > OPT_LIST_ELDERLY) continue;
        return p[0];
    } while (try < 2);
    return OPT_EXIT;
}

int so_insert(Patient* p, Patients* set)
{
    if (p == NULL) return -1;                // no patient
    if (set == NULL) return -2;              // no group
    if (set->size >= set->limit) return -3;  // full
    set->p[set->size] = *p;                  // plain copy
    set->size += 1;
    if (p->age >= ELDERLY_AGE) set->elderly += 1;
    return 0;
}

Patient so_factory(void)
{
    static id     = 1000;
    Patient proto = {0};
    proto.id      = id;
    proto.age     = 18 + rand() % 80;
    char name[80] = {0};
    sprintf(name, "Name XYZ%d", id);
    strcpy(proto.name, name);
    if (rand() % 100 > 19)
        proto.insurance[0] = 0;
    else
    {
        sprintf(name, "Insurance %d Co.", id);
        strcpy(proto.insurance, name);
    };
    ++id;
    if (id >= 1999) id = 1000;  // reset
    return proto;
}
© www.soinside.com 2019 - 2024. All rights reserved.