繁体   English   中英

每当我在此代码中编辑患者信息时,我都会遇到此消息“检测到堆栈粉碎 ***:终止中止”

[英]I face this message "stack smashing detected ***: terminated Aborted" whenever i edit the patient information in this code

本项目是诊所中的控制系统,使用C语言。 我面临的问题是每当我运行代码并写入患者的姓名和信息,并且当我修改该信息并对其进行编辑时,都会出现此消息“ stack smashing detected

#include <stdio.h>
#include <stdlib.h>
#define size 100
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned long int u32;
typedef signed char s8;
typedef signed short int s16;
typedef signed long int s32;
typedef float f32;
typedef double f64;
u8 cnt;
static u8 i = 0;
void printGreetings(void);
void reserve(u8 sloto, u8 idr);
u8 addpat(void);
void editpat(u8 ido);
void viewpat(u8 ide_u);
void view_resv(u8 idr);
void delete_res(u8 idr);
void printGreetings(void)
{

    printf("For Admin Mode Enter [1] \n");
    printf("For Patient Mode Enter [2] \n");
}
typedef struct Patient
{
    u32 name[16];
    u8 age;
    u32 gender[16];
    u8 id;

} newpa;
newpa pat[size];

void admin(void)
{
    printf("To enter Patient record press (1) \n");
    printf("To edit patient record press  (2) \n");
    printf("To reserve a slot with a doctor press (3) \n");
    printf("To cancel reservation press (4) \n");
}
u8 slots[6] = {0, 8, 2, 3, 4, 5};
u8 slotres[size];
int main()
{
    u8 ide;
    u8 ur_id;
    u8 op;
    u8 sloter = 1, idw = 1;
    u16 pass;
    u8 many;
    u8 choico;
    printGreetings();

    do
    {
        printf("Please enter Your choice(1 or 2): \n");
        scanf("%d", &op);
        switch (op)
        {
        case 1:
            // Admin Mode

            printf("Please enter your password: \n");
            scanf("%d", &pass);
            if (pass == 1234)
            {
                printf("welcome Sir \n");

                admin();
                u8 op;
                printf("please enter the choice: \n");
                scanf("%d", &op);
                switch (op)
                {
                case 1:
                    addpat();
                    printf("New patient is added successfully \n");

                    break;

                case 2:
                    // editing
                    printf("Please enter the id: ");
                    scanf("%d", &ide);
                    editpat(ide);
                    continue;

                    break;

                case 3:
                    // reserve

                    printf("there are 5 available slots ");
                    printf("2pm to 2:30pm, 2:30pm to 3pm, 3pm to 3:30pm \n");
                    printf("4pm to 4:30pm and 4:30pm to 5pm \n");
                    printf("Please enter the id: ");
                    scanf("%d", &idw);
                    printf("Please enter the slot you want to reserve: ");
                    scanf("%d", &sloter);
                    reserve(sloter, idw);

                    break;

                case 4:
                    // cancel
                    printf("Please enter the user id : ");
                    scanf("%d", &many);
                    delete_res(many);

                    break;

                default:
                    printf("Please enter the choice correctly \n");

                    break;
                }
            }
            else
            {
                printf("Wrong password, please try again \n");
                cnt++;
                if (cnt == 3)
                {
                    exit(2);
                }
            }

            break;

        case 2:
            // patient choice

            printf("Please enter the id \n");
            scanf("%d", &ur_id);
            printf("To view Information press 1: \n To view reservation press 2: \n");
            scanf("%d", &choico);
            if (choico == 1)
                viewpat(ur_id);
            else if (choico == 2)
                view_resv(ur_id);
            else
                printf("Invalid choice");
            break;

        default:
            printf("Invalid Choice, Please try to enter your choice correctly \n");

            break;
        }

    } while (1);

    return 0;
}
u8 addpat(void)
{

    i++;
    pat[i].id = i;
    fflush(stdin);
    printf("please enter the patient name: ");
    scanf("%s", pat[i].name);
    fflush(stdin);
    printf("please enter the patient age: ");
    scanf("%d", &pat[i].age);
    fflush(stdin);
    printf("please enter the patient gender: ");
    scanf("%s", pat[i].gender);

    static u8 j;
    for (j = 1; j <= i; j++)
    {
        printf("The patient Id is:  %d \n", pat[j].id);
        printf("The patient name is: %s \n", pat[j].name);
        printf("The patient age is:  %d \n", pat[j].age);
        printf("The patient gender is:  %s \n", pat[j].gender);
        printf("________________________________________ \n");
    }
    return pat[i].id;
}
void editpat(u8 ido)
{
    u8 edit;
    if (ido != 0 && ido <= i)
    {
        printf("The patient Id is:  %d \n", pat[ido].id);
        printf("The patient name is: %s \n", pat[ido].name);
        printf("The patient age is:  %d \n", pat[ido].age);
        printf("The patient gender is:  %s \n", pat[ido].gender);
    }
    else
    {

        printf("The id is not found !!!");
    }
    printf("to edit press 1 \n");
    scanf("%d", &edit);
    if (edit == 1)
    {
        fflush(stdin);
        printf("please enter the new patient name: ");
        scanf("%s", pat[ido].name);
        fflush(stdin);
        printf("please enter the new patient age: ");
        scanf("%d", &pat[ido].age);
        fflush(stdin);
        printf("please enter the  new patient gender: ");
        scanf("%s", pat[ido].gender);

        pat[i].id = ido;

        printf("The new patient info : \n");
        printf("The patient Id is:  %d \n", pat[ido].id);
        printf("The patient name is: %s \n", pat[ido].name);
        printf("The patient age is:  %d \n", pat[ido].age);
        printf("The patient gender is:  %s \n", pat[ido].gender);
    }
    else
    {
        printf("Undefined choice \n");
    }
}
void viewpat(u8 ide_u)
{
    if (ide_u != 0 && ide_u <= i)
    {
        printf("The  patient info : \n");
        printf("The patient Id is:  %d \n", pat[ide_u].id);
        printf("The patient name is: %s \n", pat[ide_u].name);
        printf("The patient age is:  %d \n", pat[ide_u].age);
        printf("The patient gender is:  %s \n", pat[ide_u].gender);
    }
    else
    {
        printf("INVALID ID \n");
    }
}
void reserve(u8 sloto, u8 idr)
{
    // check
    u8 flag_t = 0;
    if (idr != 0 && idr <= i)
    {
        if (slots[sloto] != 0 && slots[sloto] != 1)
        {
            slots[sloto] = 1;
            slotres[idr] = sloto;
        }
        else
        {

            printf("The slot is reserved previously \n");
            flag_t = 1;
        }
    }
    else
    {
        printf("Invalid Id \n");
    }

    if (slotres[idr] == 1 && flag_t == 0)
    {
        printf("slot 2pm to 2:30pm is reserved \n");
    }
    else if (slotres[idr] == 2 && flag_t == 0)
    {
        printf("slot 2:30 pm to 3 pm is reserved \n");
    }
    else if (slotres[idr] == 3 && flag_t == 0)
    {
        printf("slot 3 pm to 3:30pm is reserved \n");
    }
    else if (slotres[idr] == 4 && flag_t == 0)
    {
        printf("slot 3:30 pm to 4 pm is reserved \n");
    }
    else if (slotres[idr] == 5 && flag_t == 0)
    {
        printf("slot 4 pm to 5:30 pm is reserved \n");
    }
    else
    {
        printf("Nothing is reserved \n");
    }
}
void delete_res(u8 idr)
{
    u8 temp;
    if (idr != 0 && idr <= i)
    {
        // code
        if (slotres[idr] == 0)
        {
            printf("There's no previous reservation \n");
        }
        else
        {
            temp = slotres[idr];
            slotres[idr] = 0;
            slots[temp] = temp;
            printf("The Cancellation is successfull \n");
        }
    }
    else
    {

        printf("Invalid ID \n");
    }
}

void view_resv(u8 idr)
{
    if (idr != 0 && idr <= i)
    {
        if (slotres[idr] == 1)
        {
            printf("you're reserved 2pm to 2:30pm slot \n");
        }
        else if (slotres[idr] == 2)
        {
            printf("you're reserved 2:30pm to 3pm slot \n");
        }
        else if (slotres[idr] == 3)
        {
            printf("you're reserved 3pm to 3:30pm slot \n");
        }
        else if (slotres[idr] == 4)
        {
            printf("you're reserved 3:30 pm to 4pm slot \n");
        }
        else if (slotres[idr] == 5)
        {
            printf("you're reserved 4pm to 5:30pm slot \n");
        }
        else
        {
            printf("Nothing is reserved \n");
        }
    }
    else
    {
        printf("Enter the correct id \n");
    }
}

这可能是什么原因,我该如何纠正? 我希望患者数据能够被无误地修改,包括年龄、姓名和性别。

几个问题...

  1. 患者结构中的字符串应该是char而不是u32
  2. editpat中, pat[i].id = ido; 应该是: pat[ido] = ido; . 否则,您可能会超出数组的末尾(即 UB(未定义行为))。
  3. fflush(stdin)是错误的。 fflush对于输入流是未定义的。
  4. 有很多重复序列。 最好拆分成函数。
  5. 很难看到将i用于全球患者计数。 最好重命名为更具描述性的名称(例如patcount )。
  6. 做(例如) pat[j].whatever到处都可能导致错误。 最好使用指针并执行(例如) p->whatever

这是修改后的代码。 是有注释的。 可能仍然存在一些错误。 但是,我测试了你的场景,堆栈至少没有崩溃:

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

#define size 100

typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned long int u32;
typedef signed char s8;
typedef signed short int s16;
typedef signed long int s32;
typedef float f32;
typedef double f64;

u8 cnt;
static u8 patcount = 0;

void printGreetings(void);
void reserve(u8 sloto, u8 idr);
u8 addpat(void);
void editpat(u8 ido);
void viewpat(u8 ide_u);
void view_resv(u8 idr);
void delete_res(u8 idr);

void
printGreetings(void)
{

    printf("For Admin Mode Enter [1]\n");
    printf("For Patient Mode Enter [2]\n");
}

typedef struct Patient {
// NOTE/BUG: this should be a char array
#if 0
    u32 name[16];
#else
    char name[16];
#endif
    u8 age;
#if 0
    u32 gender[16];
#else
    char gender[16];
#endif
    u8 id;

} newpa;
newpa pat[size];

void
admin(void)
{
    printf("To enter Patient record press (1)\n");
    printf("To edit patient record press  (2)\n");
    printf("To reserve a slot with a doctor press (3)\n");
    printf("To cancel reservation press (4)\n");
}

u8 slots[6] = { 0, 8, 2, 3, 4, 5 };
u8 slotres[size];

#define ASKSTR(_prompt,_str) \
    askstr(_prompt,_str,sizeof(_str))

void
askstr(const char *prompt,char *buf,size_t buflen)
{
    char *cp;

    static int fileflg = -1;
    if (fileflg < 0) {
        struct termios tio;
        fileflg = tcgetattr(fileno(stdin),&tio) < 0;
    }

    printf("%s: ",prompt);
    fflush(stdout);

    if (fgets(buf,buflen,stdin) == NULL)
        exit(7);

    if (fileflg)
        fputs(buf,stdout);

    // strip newline
    buf[strcspn(buf,"\n")] = 0;
}

int
asknum(const char *prompt)
{
    char *cp;
    char buf[100];
    int ret = -1;

    ASKSTR(prompt,buf);

    do {
        errno = 0;
        int num = strtol(buf,&cp,10);

        if (errno)
            break;

        if (*cp == 0)
            ret = num;
    } while (0);

    return ret;
}

int
main(void)
{
    u8 ide;
    u8 ur_id;
    u8 op;
    u8 sloter = 1,
        idw = 1;
    u16 pass;
    u8 many;
    u8 choico;

#if 0
    printGreetings();
#endif

    do {
        while (1) {
            printGreetings();
            op = asknum("Please enter Your choice(1 or 2)");
            if ((op == 1) || (op == 2))
                break;
        }

        switch (op) {
        case 1:
            // Admin Mode

            pass = asknum("Please enter your password");
            if (pass == 1234) {
                printf("welcome Sir\n");

                admin();
                u8 op;

                op = asknum("please enter the choice");
                switch (op) {
                case 1:
                    addpat();
                    printf("New patient is added successfully\n");
                    break;

                case 2:
                    // editing
                    ide = asknum("Please enter the id");
                    editpat(ide);
                    continue;
                    break;

                case 3:
                    // reserve

                    printf("there are 5 available slots");
                    printf("2pm to 2:30pm, 2:30pm to 3pm, 3pm to 3:30pm\n");
                    printf("4pm to 4:30pm and 4:30pm to 5pm\n");
                    idw = asknum("Please enter the id: ");
                    sloter = asknum("Please enter the slot you want to reserve");
                    reserve(sloter, idw);
                    break;

                case 4:
                    // cancel
                    many = asknum("Please enter the user id : ");
                    delete_res(many);
                    break;

                default:
                    printf("Please enter the choice correctly\n");
                    break;
                }
            }
            else {
                printf("Wrong password, please try again\n");
                cnt++;
                if (cnt == 3) {
                    exit(2);
                }
            }
            break;

        case 2:
            // patient choice

            do {
                ur_id = asknum("Please enter the id");
            } while (ur_id < 0);

            choico = asknum("To view Information press 1:\n"
                "To view reservation press 2");

            if (choico == 1)
                viewpat(ur_id);
            else if (choico == 2)
                view_resv(ur_id);
            else
                printf("Invalid choice");
            break;

        default:
            printf("Invalid Choice, Please try to enter your choice correctly\n");
            break;
        }
    } while (1);

    return 0;
}

void
showpat(newpa *p)
{
    printf("The patient Id is:  %d\n", p->id);
    printf("The patient name is: %s\n", p->name);
    printf("The patient age is:  %d\n", p->age);
    printf("The patient gender is:  %s\n", p->gender);
}

u8
addpat(void)
{

#if 0
    i++;
#else
    patcount++;
#endif

    newpa *p = &pat[patcount];
    p->id = patcount;

    ASKSTR("please enter the patient name",p->name);
    p->age = asknum("please enter the patient age");

    ASKSTR("please enter the patient gender",p->gender);

    static u8 j;

#if 0
    for (j = 1; j <= i; j++) {
#else
    for (j = 0; j < patcount; j++) {
#endif
        newpa *p = &pat[j];
        showpat(p);
        printf("________________________________________\n");
    }

    return p->id;
}

void
editpat(u8 ido)
{
    u8 edit;
    newpa *p = &pat[ido];

    if (ido != 0 && ido <= patcount) {
        showpat(p);
    }
    else {
        printf("The id is not found !!!");
    }

    edit = asknum("to edit press 1");
    if (edit == 1) {
        ASKSTR("please enter the new patient name",p->name);
        p->age = asknum("please enter the new patient age");

        ASKSTR("please enter the  new patient gender",p->gender);

#if 0
        pat[i].id = ido;
#else
        p->id = ido;
#endif

        printf("The new patient info:\n");
        showpat(p);
    }
    else {
        printf("Undefined choice\n");
    }
}

void
viewpat(u8 ide_u)
{
    if (ide_u != 0 && ide_u <= patcount) {
        printf("The  patient info :\n");
        showpat(&pat[ide_u]);
    }
    else {
        printf("INVALID ID\n");
    }
}

void
reserve(u8 sloto, u8 idr)
{
    // check
    u8 flag_t = 0;

    if (idr != 0 && idr <= patcount) {
        if (slots[sloto] != 0 && slots[sloto] != 1) {
            slots[sloto] = 1;
            slotres[idr] = sloto;
        }
        else {

            printf("The slot is reserved previously\n");
            flag_t = 1;
        }
    }
    else {
        printf("Invalid Id\n");
    }

    if (slotres[idr] == 1 && flag_t == 0) {
        printf("slot 2pm to 2:30pm is reserved\n");
    }
    else if (slotres[idr] == 2 && flag_t == 0) {
        printf("slot 2:30 pm to 3 pm is reserved\n");
    }
    else if (slotres[idr] == 3 && flag_t == 0) {
        printf("slot 3 pm to 3:30pm is reserved\n");
    }
    else if (slotres[idr] == 4 && flag_t == 0) {
        printf("slot 3:30 pm to 4 pm is reserved\n");
    }
    else if (slotres[idr] == 5 && flag_t == 0) {
        printf("slot 4 pm to 5:30 pm is reserved\n");
    }
    else {
        printf("Nothing is reserved\n");
    }
}

void
delete_res(u8 idr)
{
    u8 temp;

    if (idr != 0 && idr <= patcount) {
        // code
        if (slotres[idr] == 0) {
            printf("There's no previous reservation\n");
        }
        else {
            temp = slotres[idr];
            slotres[idr] = 0;
            slots[temp] = temp;
            printf("The Cancellation is successfull\n");
        }
    }
    else {

        printf("Invalid ID\n");
    }
}

void
view_resv(u8 idr)
{
    if (idr != 0 && idr <= patcount) {
        if (slotres[idr] == 1) {
            printf("you're reserved 2pm to 2:30pm slot\n");
        }
        else if (slotres[idr] == 2) {
            printf("you're reserved 2:30pm to 3pm slot\n");
        }
        else if (slotres[idr] == 3) {
            printf("you're reserved 3pm to 3:30pm slot\n");
        }
        else if (slotres[idr] == 4) {
            printf("you're reserved 3:30 pm to 4pm slot\n");
        }
        else if (slotres[idr] == 5) {
            printf("you're reserved 4pm to 5:30pm slot\n");
        }
        else {
            printf("Nothing is reserved\n");
        }
    }
    else {
        printf("Enter the correct id\n");
    }
}

在上面的代码中,我使用cpp条件来表示旧代码与新代码:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

注意:这可以通过unifdef -k运行文件来清理

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM