C 在执行操作时,将显示bookid';让我们换衣服吧?

C 在执行操作时,将显示bookid';让我们换衣服吧?,c,C,我已经做了一个程序,这是一个通过软件操作的小型库。当我添加两本书,然后删除第一本书时,由于del()函数中的count--,第二本书将获得与第一本书相同的图书ID。我不能依靠打印计数作为bookid。有更好的选择吗 #include<stdio.h> #include<conio.h> #include<stdlib.h> static int count; struct book { int bookid; char name[30]; char

我已经做了一个程序,这是一个通过软件操作的小型库。当我添加两本书,然后删除第一本书时,由于
del()
函数中的
count--
,第二本书将获得与第一本书相同的图书ID。我不能依靠打印计数作为bookid。有更好的选择吗

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
static int count;
struct book
{
  int bookid;
  char name[30];
  char author[30];
  float price;
};
struct book b[40];
void add(void);
void del(void);
void sort(void);
void price(void);
void print(void);
void main(void)
{
  char choice;
  while(1)
  {
    clrscr();
    printf("Enter a choice:\n 1.Add a book.\n 2.Delete a book.\n 3.Sort books by price.\n 4.To print all books details.\n 5.To print the names of the books whose price is less than 1000.\n 6.Exit\n");
    choice=getche();//doing by getch() as getche makes the program rough as it is printed
    switch(choice)
    {
      case'1':add();break;
      case'2':del();break;
      case'3':sort();break;
      case'4':print();break;
      case'5':price();break;
      case'6':exit(0);
      default:printf("Enter a valid choice.");break;
    }
  }/*switch ends*/
}
void add(void)
{
  int i;
  char ch[30];
  clrscr();
  for(i=count;i<40;i++)
  {
    printf("Enter books name:\n");
    gets(b[i].name);
    printf("Enter author's name\n");
    gets(b[i].author);
    printf("Enter price:\n");
    gets(ch);
    b[i].price=atoi(ch);
    printf("Dear User,the book has succesfully been added.The book id is %d",i);
    count++;
    break;
  } /* for ends*/
  getch();
}
void print(void)
{
  int i;
  clrscr();
  for(i=0;i<count;i++)
  {
    printf("Bookid=%d,Name=%s,Author=%s,Price=%f\n",b[i].bookid,b[i].name,b[i].author,b[i].price);
  }
  getch();
}

void del(void)
{
  int i,j;
  char ch[10];
  clrscr();
  printf("Enter book id:");
  gets(ch); // how do i put it into the structure as i dont know that which structure it belongs to
  for(i=0;i<count;i++)  //searching
  {
    if(b[i].bookid==atoi(ch))
    {
      for(j=i;j<count;j++)
      {
        b[j]=b[j+1];
      }//for j ends
    }  //if ends
  } /* for of i ends */
  count--;
  getch();
}
//void del(void)
//{

    // int i;
    // char ch[10];
     // clrscr();
 //printf("Enter book id:");
       // gets(ch);
      // for(i=0;i<40;i++)
      // {
     //  b[i]=b[i+1];
    //
   // }
    // count--;
  // printf("Dear user,delete succesful");
//getch();
//}
void sort(void)
{
  int i;
  float temp;
  for(i=0;i<40;i++)
  {
    if(b[i].price>b[i+1].price)
    {
      temp=b[i].price;
      b[i].price=b[i+1].price;
      b[i+1].price=temp;
    }
  }/*for ends*/
  printf("Dear user,the books are sorted by price.\n");

  getch();
}

void price(void)
{
  int i;
  clrscr();
  for(i=0;i<count;i++)
  {
    if(b[i].price<1000)
    {
      printf("%d.%s\n",i+1,b[i].name);
    }
  }
  getch();
}
#包括
#包括
#包括
静态整数计数;
结构体的构造
{
国际图书编号;
字符名[30];
char作者[30];
浮动价格;
};
结构书b[40];
无效添加(无效);
无效del(void);
无效排序(void);
无效价格(无效);
作废打印(作废);
真空总管(真空)
{
字符选择;
而(1)
{
clrsc();
printf(“输入选项:\n 1.添加一本书。\n 2.删除一本书。\n 3.按价格对书进行排序。\n 4.打印所有书的详细信息。\n 5.打印价格低于1000的书的名称。\n 6.退出\n”);
choice=getche();//将getch()作为getche执行会使程序在打印时变得粗糙
开关(选择)
{
案例“1”:添加();中断;
案例'2':del();break;
案例'3':sort();break;
案例'4':print();break;
案例'5':价格();中断;
案例“6”:退出(0);
默认值:printf(“输入有效选项”);break;
}
}/*开关端*/
}
无效添加(无效)
{
int i;
char-ch[30];
clrsc();
对于(i=count;i某些指针:

使用fgets而不是get,这样更安全 因为您可以指定最大buf len
在add()中没有指定图书id, 因此,它将-由于是全球性的- 保持0
你为什么需要书证?你呢 如果数组为40,请使用该数组 索引为id


您的第一个问题似乎是,您从未真正将
book
结构的
bookid
字段设置为任何值。它最终会在每个book结构中具有一些任意值,如果
del
能够正常工作,这将是纯粹的运气

你的问题就在这里:

printf("Enter books name:\n");
gets(b[i].name);
printf("Enter author's name\n");
gets(b[i].author);
printf("Enter price:\n");
gets(ch);
b[i].price=atoi(ch);
printf("Dear User,the book has succesfully been added.The book id is %d",i);
count++;
看看这段代码,告诉我在哪里设置
b[i].bookid的值。答案是无处可寻。请尝试将最后几行更改为:

b[i].bookid = i;
printf("Dear User,the book has succesfully been added.The book id is %d", b[i].bookid);
count++;
现在,如果您在调用
del
之后调用
add
,这仍然存在一个问题,因为在该代码所在的单个迭代循环中,
i
总是设置为
count
。因此,正如您所注意到的,如果
count
经常发生更改,您将分配重复的ID。一个解决方案是定义,在
add
函数的顶部,一个静态变量(在调用函数之间保留其值)指示下一个图书id应该是什么,如下所示:

void add(void)
{
  static int nextBookId = 0;
  int i = count;
  char ch[30];

  /* Do not overrun the array */
  if (count >= 40) return;

  clrscr();
  printf("Enter books name:\n");
  gets(b[i].name);
  printf("Enter author's name\n");
  gets(b[i].author);
  printf("Enter price:\n");
  gets(ch);
  b[i].price=atoi(ch);

  /* Assign the next unique book ID to this book, then increment nextBookId,
     which will retain its incremented value next time you call add() */
  b[i].bookid = nextBookId++;

  printf("Dear User,the book has succesfully been added.The book id is %d", b[i].bookid);
  count++;
  getch();
}
注意,我在顶部用一个简单的边界检查替换了您的循环

这样,您添加的每本书都会获得自己的唯一标识符,该标识符不一定对应于它在数组中的位置或添加时存在的书的数量。此方法不会重复使用以前删除的书的ID,但这可能是一种可取的行为。

一种方法是使用两个全局计数器:一个是Tyler McHenry指出,存储的图书数量,另一个给出下一个(唯一的)图书id。删除图书时,减少图书数量,但决不减少下一个图书id

我注意到,当一本书被删除时,你会将其余的书项移到一起(“压缩”它们),所以你的数组总是“密集的”。所以另一个解决方案是添加一个“已删除的”标记到书本结构。现在,删除书本时不压缩条目,但添加书本时,代码必须在数组中搜索空白位置。此外,bookid只是数组中的位置。(顺便说一下,如果您硬编码大小,如数组的大小,请执行一次。)

#定义MAXSTR(30)
结构体的构造
{
国际图书编号;
int valid;//1有效,0为空或已删除
字符名[MAXSTR];
字符作者[MAXSTR];
浮动价格;
};
#定义MAXBOOKS(40)
结构书b[MAXBOOKS];
int findEmpty()
{
int i;
对于(i=0;i
del()现在只是将书标记为无效。del()的主要部分如下所示

获取(ch); int idToDelete=atoi(ch); //找到它所属的结构 对于(i=0;i
使用in sort()而不是一次通过例程(这在所有情况下都不起作用)印刷书籍应该跳过任何一本无效的书。

Fahad,最好尽可能少地张贴代码来展示你要问的内容。张贴这段代码可能会让许多潜在的回答者阅读你的问题。如果你的问题必须包含这么多的代码,你可以考虑。如果可以把它分解成几个小问题。我的老师dint告诉我abt fgets,但这里的ppl告诉我abt it。我尝试使用fgets,只是在gets中添加了f,但参数丢失了。如果我使用数组索引作为id,如果我从其间删除一本书,那么谁来填补这个漏洞?@fahad这不像添加那么简单
f
to
会得到
fgets
之所以更安全,是因为它需要一个额外的参数来描述输入的最大长度,所以您必须提供该参数。
fgets
上的文档(对于大多数C函数的文档,只需谷歌搜索“man”):
#define MAXSTR (30)
struct book
{
  int bookid;
  int valid; // 1 is valid, 0 is empty or deleted
  char name[MAXSTR];
  char author[MAXSTR];
  float price;
};
#define MAXBOOKS (40)
struct book b[MAXBOOKS];

int findEmpty()
{
  int i;
  for (i=0; i < MAXBOOKS; i++) {
    if (! b[i].valid) return i;
  }
  return -1; // no more space
}

void add(void)
{
  int i = findEmpty();
  char ch[MAXSTR];

  if (i < 0) return; // no room for more books

  clrscr();
  printf("Enter books name:\n");
  fgets(b[i].name, MAXSTR, stdin);
  printf("Enter author's name\n");
  fgets(b[i].author, MAXSTR, stdin);
  printf("Enter price:\n");
  fgets(ch, MAXSTR, stdin);
  b[i].price=atoi(ch);

  /* Assign the empty location found to this book */
  b[i].bookid = i;
  /* mark that it is valid */
  b[i].valid = 1;

  printf("Dear User,the book has succesfully been added.The book id is %d", b[i].bookid);
  getch();
}