修改下面的程序,在从文件中读出每个记录并且显示它时,允许用户选择删除该记录或修改该记录的内容。如果删除记录,把空出来的数组空间留给下一个要读入的记录。要能够改变现有的文件内容,必须使用"r+b"模式,而不是"a+b"模式。要注意文件指针的定位,以便追加的记录不会覆盖已有的记录。最简单的方法是对存储在程序内存中的数据做所有的改变,然后再把最后的信息集写入文件中。
/* booksave.c -- 把结构内容保存到文件中 */
#include <stdio.h>
#include <stdlib.h>
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 10 /* 图书的最多本数 */
struct book { /* 建立book模板 */
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
struct book library[MAXBKS];/* 结构数组 */
int count = 0;
int index, filecount;
FILE * pbooks;
int size = sizeof(struct book);
if((pbooks = fopen("book.dat", "a+b")) == NULL)
{
fputs("Can't open book.dat file\n", stderr);
exit(1);
}
rewind(pbooks);
while(count < MAXBKS && fread(&libray[count], size,
1, pbooks) == 1)
{
if(count == 0)
puts("Current contents of book.dat: ");
printf("%s by %s: $%.2f\n", library[count].title,
library[count].author, library[count].value);
count++;
}
filecount = count;
if(count == MAXBKS)
{
fputs("The book.dat file is full.", stderr);
exit(2);
}
puts("Please add new book titles.");
puts("Press [enter] at the start of a line to stop.");
while(count < MAXBKS && gets(library[count].title) != NULL
&& library[count].title[0] != '\0')
{
puts("Now enter the author.");
gets(library[count].author);
puts("Now enter the value.");
scanf("%f", &library[count++].value);
while(getchar() != '\n')
continue; /* 清空输入行 */
if(count < MAXBKS)
puts("Enter the next title.");
}
if(count > 0)
{
puts("Here is the list of your books: ");
for(index = 0; index < count; index++)
printf("%s by %s: $%.2f\n", library[index].title,
library[index].author, library[index].value);
fwrite(&library[filecount], size, count - filecount,
pbooks);
}
else
puts("No books? Too bad.\n");
puts("Bye.\n");
fclose(pbooks);
return 0;
}

#include <stdio.h> #include <stdlib.h> #include <string.h> int count=0;//全局变量,书的个数 void read_file(struct book *p, char* filename); void display(struct book *p); void change(struct book *p); void reduce(struct book *p); void add(struct book *p); void write_file(struct book *p, char*); #define MAXTITL 40 #define MAXAUTL 40 #define MAXBKS 10 /* maximum number of books */ struct book { /* set up book template */ char title[MAXTITL]; char author[MAXAUTL]; float value; }; int main(void) { struct book library[MAXBKS]; /* array of structures */ char command[10]; read_file(library,"book.dat"); printf("select the functions:\n"); printf("d: display all book c: change a book\n"); printf("r: reduce a book a: add books\n"); printf("other: save and quit:"); while( 1 ) { gets(command); switch( command[0] ) { case 'd': display(library); break; case 'c': change(library); break; case 'r': reduce(library); break; case 'a': add(library); break; default : write_file(library,"book.dat"); return 0; } printf("select: d/c/r/a/other:"); } } void read_file(struct book *p, char* filename) { FILE * pbooks; if ((pbooks = fopen(filename, "a+b")) == NULL)//a+ 可以创造一个文件,且不清空 { printf("Can't open %s file\n", filename); exit(1); } rewind(pbooks); /* go to start of file */ while (count < MAXBKS && fread(p+count, sizeof (struct book), 1, pbooks) == 1) count++; fclose(pbooks); printf("read %s successfully! There are %d books.\n", filename, count); } void display(struct book *p) { int i; if ( count == 0 ) printf("There is no book.\n"); printf("book list for %d books:\n",count); for(i=0; i<count; i++) printf("%s by %s: $%.2f\n",p[i].title, p[i].author, p[i].value); } void change(struct book *p) { int i; char title[MAXTITL]; printf("input the name of the book which you want change:"); gets(title); for(i=0; i<count; i++) if ( strcmp(p[i].title, title) == 0 ) { puts("Please add new a book title."); gets(p[i].title); puts("Now enter the author."); gets(p[i].author); puts("Now enter the value."); scanf("%f", &p[i].value); getchar(); printf("the book has been changed!\n"); return; } printf("error!the book is not in the list\n"); return; } void reduce(struct book *p) { int i; char title[MAXTITL]; if(count == 0) { printf("error! book list is empty!"); return; } printf("input the name of the book which you want change:"); gets(title); for(i=0; i<count; i++) if ( strcmp(p[i].title, title) == 0 ) { p[i] = p[count-1]; strcpy(p[count-1].title, ""); strcpy(p[count-1].author, ""); p[count-1].value=0; count--; printf("%s has been delete from book list\n", title); return; } printf("error! %s is not in book list\n", title); return; } void add(struct book *p) { if (count == MAXBKS) { fputs("error!The book.dat file is full.", stderr); return; } puts("Please add new book titles."); puts("Press [enter] at the start of a line to stop."); while (count < MAXBKS && gets(p[count].title) != NULL && p[count].title[0] != '\0') { puts("Now enter the author."); gets(p[count].author); puts("Now enter the value."); scanf("%f", &p[count++].value); getchar();//eat '\n' if (count < MAXBKS) puts("Enter the next title."); else puts("The book list file is full."); } } void write_file(struct book *p, char *str) { FILE * pbooks; pbooks = fopen(str, "wb");//将文件以可写模式打开,目的是清空文件内容 pbooks = fopen(str, "r+b"); fwrite(p, sizeof (struct book), count, pbooks); fclose(pbooks); }