为什么输入书籍信息太多了,占满一页的时候,下面的信息的格式就出错了。这是软件的问题 还是我代码的问题啊?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <Windows.h>
#include <conio.h>
char ch, c, h;//选择 这是一个定义了三个字符类型变量的语句,分别为 ch、c 和 h。
struct BOOK
{
char ISBN[11];//图书登录号
char bookname[50];//书名
char writer[50];//作者
char ICS[20];//图书分类号
char publisher[50];//出版单位
char data[11];//出版日期
float price;//价格
int num;//数量
struct BOOK* next;
};
struct BOOK* head;
struct BOOK* p;
void gotoxy(int x, int y);//光标移动
void JM();//界面
void DelJM();//删除功能界面
void Next();//输入y继续,输入其他键退出
void output(struct BOOK* head);//输出链表
void CL();//创建保存链表
void Save();//保存提示框
void Del();//删除提示框
void Succeed();//成功
void FileSave();//文件保存
void PXJM();//排序界面
void FileRead(struct BOOK* HEAD);//文件读取
void DelWriter(struct BOOK* HEAD);//删除作者
void DelBook(struct BOOK* HEAD);//删除图书(编号或书名)
void PX_b(struct BOOK* HEAD);//编号排序
void PX_p(struct BOOK* HEAD);//价格排序
void Check();//图书查询
void Change();//图书信息修改
int FRN();//判断是否文件为空
void menu();//主菜单
void menu5();//选项5复菜单
void menu3();//选项3复菜单
int ReCheck(char str[]);//判断输入编号是否重复
//主函数:
int main(void)
{
menu();
return 0;
}
//自定义函数:
void gotoxy(int x, int y)
{
COORD pos = { x, y };
HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(Out, pos);
}
void JM()
{
system("cls");
printf("*请最大化使用*");
gotoxy(30, 4); printf("*********图书管理系统*********");
gotoxy(30, 6); printf(" | 1.图书信息录入 |");
gotoxy(30, 8); printf(" | 2.图书信息查询 |");
gotoxy(30, 10); printf(" | 3.图书信息删除 |");
gotoxy(30, 12); printf(" | 4.图书信息修改 |");
gotoxy(30, 14); printf(" | 5.图书信息总览 |");
gotoxy(30, 16); printf(" | 6.退出程序 |");
gotoxy(36, 18); printf("输入序号,选择功能");
}
void Next()
{
printf("输入y继续,输入其他键退出");
}
void Continue()
{
system("cls");
gotoxy(20, 10); printf("----------------------------------------\n");
gotoxy(20, 12); printf("| |\n");
gotoxy(20, 14); printf("| Continue to enter information? |\n");
gotoxy(20, 16); printf("| y / n |\n");
gotoxy(20, 18); printf("| |\n");
gotoxy(20, 20); printf("----------------------------------------\n");
gotoxy(20, 22); printf(" 输入y继续录入信息,输入n结束录入!");
}
void Save()
{
system("cls");
gotoxy(30, 10); printf("---------------------------\n");
gotoxy(30, 12); printf("| |\n");
gotoxy(30, 14); printf("| Are you save it ? |\n");
gotoxy(30, 16); printf("| y / n |\n");
gotoxy(30, 18); printf("| |\n");
gotoxy(30, 20); printf("---------------------------\n");
gotoxy(30, 22); printf(" 输入y保存!输入n取消!");
}
void Del()
{
system("cls");
gotoxy(30, 10); printf("---------------------------\n");
gotoxy(30, 12); printf("| |\n");
gotoxy(30, 14); printf("| Are you delete it ? |\n");
gotoxy(30, 16); printf("| y / n |\n");
gotoxy(30, 18); printf("| |\n");
gotoxy(30, 20); printf("---------------------------\n");
gotoxy(30, 22); printf(" 输入y保存!输入n取消!");
}
void DelJM()
{
system("cls");
gotoxy(30, 11); printf("*********图书管理系统*********");
gotoxy(30, 13); printf(" | 1.删除某作者图书 |");
gotoxy(30, 15); printf(" | 2.编号或书名删除 |");
gotoxy(30, 17); printf(" | 3.返回系统主界面 |");
gotoxy(36, 25); printf(" 输入序号,选择功能");
//c = getch();
}
void PXJM()
{
system("cls");
gotoxy(30, 11); printf("*********图书管理系统*********");
gotoxy(30, 13); printf(" | 1.按图书编号排序 |");
gotoxy(30, 15); printf(" | 2.按图书价格排序 |");
gotoxy(30, 17); printf(" | 3.返回系统主界面 |");
gotoxy(36, 19); printf(" 输入序号,选择功能");
}
void CL()//创建链表
{
head->next = NULL;
p = (struct BOOK*)malloc(sizeof(struct BOOK));
p->next = NULL;
loop:
{
struct BOOK* s = (struct BOOK*)malloc(sizeof(struct BOOK));
gotoxy(10, 11); printf("请输入图书编号:");
loop1:scanf("%s", s->ISBN);
if (ReCheck(s->ISBN) == -1)
{
system("cls");
gotoxy(30, 11); printf("输入的编号重复!请重新输入编号:");
goto loop1;
}
gotoxy(10, 13); printf("请输入书名:");
scanf("%s", s->bookname);
gotoxy(10, 15); printf("请输入作者姓名:");
scanf("%s", s->writer);
gotoxy(10, 17); printf("请输入图书分类号:");
scanf("%s", s->ICS);
gotoxy(10, 19); printf("请输入图书出版单位:");
scanf("%s", s->publisher);
gotoxy(10, 21); printf("请输入图书出版日期(年):");
scanf("%s", s->data);
gotoxy(10, 23); printf("请输入图书价格(元):");
scanf("%f", &s->price);
gotoxy(10, 25); printf("请输入图书数量(本):");
scanf("%d", &s->num);
if (head->next == NULL)
{
head->next = s;
s->next = NULL;
}
else
{
p->next = s;
s->next = NULL;
}
p = s;
//文件存储
Save();
char a;
loop2:
a = getch();
if (a == 'y' || a == 'Y')
{
FileSave();
Succeed();
Sleep(1000);
}
else if (a == 'n' || a == 'N')
{
system("cls");
gotoxy(40, 25); printf("修改未保存!");
Sleep(1000);
system("cls");
}
else
{
goto loop2;
}
gotoxy(30, 25); Continue();
ch = getch();
if (ch == 'y' || ch == 'Y')
{
system("cls");
goto loop;
}
}
}
void output(struct BOOK* s)
{
int t = 0;
system("cls");
struct BOOK* p = (struct BOOK*)malloc(sizeof(struct BOOK));
p = s;
gotoxy(1, 6); printf("------------------------------------------------------------------------------------------------------------------------------\n");
gotoxy(4, 8); printf("图书登录号 书名 作者 分类号 出版单位 出版时间 图书价格(元) 图书数量\n");
gotoxy(1, 10); printf("------------------------------------------------------------------------------------------------------------------------------\n");
while (p->next != NULL)
{
gotoxy(4, 11 + t); printf("%s", p->next->ISBN);
gotoxy(19, 11 + t); printf("%s", p->next->bookname);
gotoxy(42, 11 + t); printf("%s", p->next->writer);
gotoxy(62, 11 + t); printf("%s", p->next->ICS);
gotoxy(74, 11 + t); printf("%s", p->next->publisher);
gotoxy(91, 11 + t); printf("%s", p->next->data);
gotoxy(103, 11 + t); printf("%g", p->next->price);
gotoxy(120, 11 + t); printf("%d\n", p->next->num);
t = t + 2;
p = p->next;
}
}
void FileSave()
{
char a;
a = getch();
system("cls");
if (a == 'y' || a == 'Y')
{
FILE* fp = fopen("bookinformation.txt", "a");
if (fp == NULL)
{
printf("打开文件失败!\n");
return;
}
fprintf(fp, "%s %s %s %s %s %s %g %d\n", p->ISBN, p->bookname, p->writer, p->ICS, p->publisher, p->data, p->price, p->num);
fclose(fp);
}
}
void FileRead(struct BOOK* HEAD)
{
FILE* fp = fopen("bookinformation.txt", "rt");
if (fp == NULL)
{
printf("文件打开失败!\n");
return;
}
struct BOOK* p = (struct BOOK*)malloc(sizeof(struct BOOK));
p->next = NULL;
while (!feof(fp))//判断是否读到文件尾
{
struct BOOK* s = (struct BOOK*)malloc(sizeof(struct BOOK));
fscanf(fp, "%s %s %s %s %s %s %f %d\n", s->ISBN, s->bookname, s->writer, s->ICS, s->publisher, s->data, &s->price, &s->num);
if (HEAD->next == NULL)
{
HEAD->next = s;
s->next = NULL;
}
else
{
p->next = s;
s->next = NULL;
}
p = s;
}
}
void DelWriter(struct BOOK* HEAD)
{
int t = 0;
int a = 0;//删除后链表长度计数器
char ch[50];
struct BOOK* q1 = (struct BOOK*)malloc(sizeof(struct BOOK));
q1->next = NULL;
struct BOOK* q2 = (struct BOOK*)malloc(sizeof(struct BOOK));
q2->next = NULL;
q1 = HEAD;
gotoxy(30, 20); printf("请输入要删除的图书的作者:");
scanf("%s", ch);
while (q1->next != NULL)
{
a++;
q2 = q1->next;
if (q2->next != NULL && (strcmp(ch, q2->writer) == 0))
{
t++;
a--;
q1->next = q2->next;
q2 = q2->next;
continue;
}
else if (q2->next == NULL && (strcmp(ch, q2->writer) == 0))
{
t++;
a--;
q1->next = NULL;
break;
}
q1 = q1->next;
}
if (t != 0)
{
loop:
Del();
char c;
c = getch();
if (c == 'y' || c == 'Y')
{
q1 = HEAD->next;
FILE* fp = fopen("bookinformation.txt", "wt");
if (fp == NULL)
{
printf("打开文件失败!\n");
return;
}
for (int i = 0; i < a; i++)
{
fprintf(fp, "%s %s %s %s %s %s %g %d\n", q1->ISBN, q1->bookname, q1->writer, q1->ICS, q1->publisher, q1->data, q1->price, q1->num);
q1 = q1->next;
}
fclose(fp);
Succeed();
Sleep(1000);
system("cls");
}
else if (c == 'n' || c == 'N')
{
system("cls");
gotoxy(33, 22); printf("修改未保存!");
gotoxy(33, 25); printf("按任意键返回删除菜单!");
getch();
menu3();
}
else
{
goto loop;
}
}
else if (t == 0)
{
gotoxy(30, 22); printf("没有找到此作者!!!");
Sleep(1000);
}
}
void DelBook(struct BOOK* HEAD)
{
int t = 0;
int a = 0; // 删除后链表长度计数器
char ch[50];
struct BOOK* q1 = HEAD;
struct BOOK* q2 = NULL; // 注意这里初始化为 NULL
gotoxy(35, 20); printf("请输入要删除的图书的编号或书名:");
scanf("%s", ch);
while (q1->next != NULL)
{
a++;
q2 = q1->next;
if (q2 != NULL && (strcmp(ch, q2->ISBN) == 0 || strcmp(ch, q2->bookname) == 0))
{
t++;
a--;
q1->next = q2->next;
// 更新下一个节点并释放当前遍历指向的内存空间
struct BOOK* tmp = q2;
q2 = q2->next;
free(tmp);
continue;
}
q1 = q1->next;
}
if (t != 0)
{
loop:
Del();
char c;
c = getch();
if (c == 'y' || c == 'Y')
{
q1 = HEAD->next;
// 写入模式应为 wt,表示写入,如果写入失败应进行错误处理
FILE* fp = fopen("bookinformation.txt", "wt");
if (fp == NULL)
{
printf("打开文件失败!\n");
return;
}
for (int i = 0; i < a; i++)
{
fprintf(fp, "%s %s %s %s %s %s %g %d\n", q1->ISBN, q1->bookname, q1->writer, q1->ICS, q1->publisher, q1->data, q1->price, q1->num);
q1 = q1->next;
}
// 写入完成后关闭文件
fclose(fp);
Succeed();
Sleep(1000);
system("cls");
}
else if (c == 'n' || c == 'N')
{
system("cls");
gotoxy(33, 22); printf("修改未保存!");
gotoxy(33, 25); printf("按任意键返回删除菜单!");
getch();
menu3();
}
else
{
goto loop;
}
}
else
{
gotoxy(30, 22); printf("这本书还没有入库呢!!!");
}
}
void PX_b(struct BOOK* HEAD)
{
struct BOOK* q = (struct BOOK*)malloc(sizeof(struct BOOK));
q = HEAD;
int a = 0;//链表长度计数器
while (q->next != NULL)
{
a++;
q = q->next;
}
struct BOOK* q1 = (struct BOOK*)malloc(sizeof(struct BOOK));
q1->next = NULL;
struct BOOK* q2 = (struct BOOK*)malloc(sizeof(struct BOOK));
q2->next = NULL;
if (HEAD->next->next != NULL)
{
for (int i = 0; i < a - 1; i++)
{
q = HEAD;
q1 = q->next;
q2 = q1->next;
while (q2->next != NULL)
{
if (strcmp(q1->ISBN, q2->ISBN) > 0)
{
q->next = q1->next;
q1->next = q2->next;
q2->next = q1;
q2 = q1->next;
q = q->next;
continue;
}
q = q->next;
q1 = q1->next;
q2 = q2->next;
}
if (strcmp(q1->ISBN, q2->ISBN) > 0)
{
q->next = q2;
q2->next = q1;
q1->next = NULL;
}
}
}
q1 = HEAD->next;
FILE* fp = fopen("bookinformation.txt", "wt");
if (fp == NULL)
{
printf("打开文件失败!\n");
return;
}
for (int i = 0; i < a; i++)
{
fprintf(fp, "%s %s %s %s %s %s %g %d\n", q1->ISBN, q1->bookname, q1->writer, q1->ICS, q1->publisher, q1->data, q1->price, q1->num);
q1 = q1->next;
}
fclose(fp);
}
void PX_p(struct BOOK* HEAD)
{
struct BOOK* q = (struct BOOK*)malloc(sizeof(struct BOOK));
q = HEAD;
int a = 0;//链表长度计数器
while (q->next != NULL)
{
a++;
q = q->next;
}
struct BOOK* q1 = (struct BOOK*)malloc(sizeof(struct BOOK));
q1->next = NULL;
struct BOOK* q2 = (struct BOOK*)malloc(sizeof(struct BOOK));
q2->next = NULL;
if (HEAD->next->next != NULL)
{
for (int i = 0; i < a - 1; i++)
{
q = HEAD;
q1 = q->next;
q2 = q1->next;
while (q2->next != NULL)
{
if (q1->price > q2->price)
{
q->next = q1->next;
q1->next = q2->next;
q2->next = q1;
q2 = q1->next;
q = q->next;
continue;
}
q = q->next;
q1 = q1->next;
q2 = q2->next;
}
if (q1->price > q2->price)
{
q->next = q2;
q2->next = q1;
q1->next = NULL;
}
}
}
q1 = HEAD->next;
FILE* fp = fopen("bookinformation.txt", "wt");
if (fp == NULL)
{
printf("打开文件失败!\n");
return;
}
for (int i = 0; i < a; i++)
{
fprintf(fp, "%s %s %s %s %s %s %g %d\n", q1->ISBN, q1->bookname, q1->writer, q1->ICS, q1->publisher, q1->data, q1->price, q1->num);
q1 = q1->next;
}
fclose(fp);
}
void Change()
{
int t = 0;
system("cls");
FileRead(head);
struct BOOK* q = (struct BOOK*)malloc(sizeof(struct BOOK));
q = head;
char ch[50];
gotoxy(30, 15); printf("请输入需要查询图书的登录号号或书名:");
scanf("%s", ch);
while (q->next != NULL)
{
if (strcmp(ch, q->next->ISBN) == 0 || strcmp(ch, q->next->bookname) == 0)
{
t++;
struct BOOK* q1 = (struct BOOK*)malloc(sizeof(struct BOOK));
q1 = q->next;
system("cls");
struct BOOK* s = (struct BOOK*)malloc(sizeof(struct BOOK));
gotoxy(10, 11); printf("请重新输入图书登录号:");
scanf("%s", s->ISBN);
gotoxy(10, 13); printf("请重新输入书名:");
scanf("%s", s->bookname);
gotoxy(10, 15); printf("请重新输入作者姓名:");
scanf("%s", s->writer);
gotoxy(10, 17); printf("请重新输入图书分类号:");
scanf("%s", s->ICS);
gotoxy(10, 19); printf("请重新输入图书出版单位:");
scanf("%s", s->publisher);
gotoxy(10, 21); printf("请重新输入图书出版时间(年):");
scanf("%s", s->data);
gotoxy(10, 23); printf("请重新输入图书价格(元):");
scanf("%f", &s->price);
gotoxy(10, 25); printf("请重新输入图书数量(本):");
scanf("%d", &s->num);
char a;
Save();
loop:a = getch();
if (a == 'y' || a == 'Y')
{
Succeed();
Sleep(1000);
system("cls");
q->next = s;
s->next = q1->next;
}
else if (a == 'n' || a == 'N')
{
system("cls");
gotoxy(40, 15); printf("修改未保存!");
Sleep(1000);
system("cls");
}
else
{
gotoxy(30, 24); printf("请重新输入y或n!");
goto loop;
}
}
q = q->next;
}
if (t != 0)
{
q = head;
int a = 0;//链表长度计数器
while (q->next != NULL)
{
a++;
q = q->next;
}
q = head->next;
FILE* fp = fopen("bookinformation.txt", "wt");
if (fp == NULL)
{
printf("打开文件失败!\n");
return;
}
for (int i = 0; i < a; i++)
{
fprintf(fp, "%s %s %s %s %s %s %g %d\n", q->ISBN, q->bookname, q->writer, q->ICS, q->publisher, q->data, q->price, q->num);
q = q->next;
}
fclose(fp);
}
else
{
gotoxy(30, 22); printf("这本书还没有入库呢!!!");
}
}
void Check()
{
system("cls");
FileRead(head); // 定义 FileRead 函数,并将其包含在代码文件中
struct BOOK* q = head; // q 直接赋值为 head,不需要再分配内存空间
char ch[50];
gotoxy(30, 15); printf("请输入需要查询图书的编号或书名或作者:");
gotoxy(30, 17); scanf("%s", ch);
system("cls");
int t = 0;
while (q != NULL) // 使用 q 指针遍历链表,对指针进行更新
{
if (strcmp(ch, q->ISBN) == 0 || strcmp(ch, q->bookname) == 0 || strcmp(ch, q->writer) == 0)
{
gotoxy(1, 6); printf("------------------------------------------------------------------------------------------------------------------------------\n");
gotoxy(4, 8); printf("图书登录号 书名 作者 分类号 出版单位 出版时间 图书价格(元) 图书数量(本)\n");
gotoxy(1, 10); printf("------------------------------------------------------------------------------------------------------------------------------\n");
gotoxy(4, 11 + t); printf("%s", q->ISBN);
gotoxy(19, 11 + t); printf("%s", q->bookname);
gotoxy(42, 11 + t); printf("%s", q->writer);
gotoxy(62, 11 + t); printf("%s", q->ICS);
gotoxy(74, 11 + t); printf("%s", q->publisher);
gotoxy(91, 11 + t); printf("%s", q->data);
gotoxy(103, 11 + t); printf("%g", q->price);
gotoxy(120, 11 + t); printf("%d\n", q->num);
t += 2;
}
q = q->next; // 更新 q 指针的指向
}
if (t == 0)
{
system("cls");
gotoxy(30, 11); printf("这本书还没有添加入库!!!");
}
}
void Succeed()
{
system("cls");
gotoxy(30, 20); printf("---------------------------\n");
gotoxy(30, 22); printf("| 成 功 ! |\n");
gotoxy(30, 24); printf("---------------------------\n");
}
int FRN()
{
FILE* fp;
if ((fp = fopen("bookinformation.txt", "rt") )== NULL)
{
return -1;
}
else
{
return 0;
}
}
void menu()
{
head = (struct BOOK*)malloc(sizeof(struct BOOK));
head->next = NULL;
system("cls");
char str;
JM();
str = getch();
switch (str)
{
case '1':
system("cls");
CL();
system("cls");
gotoxy(30, 25); printf("按任意键返回主界面!");
getch();
menu();
break;
case '2':
if (FRN() == 0)
{
Check();
}
else
{
system("cls");
gotoxy(30, 13); printf("还没添加一本图书信息呢,先去添加一本吧!");
}
gotoxy(30, 15); printf("按任意键返回主界面!");
getch();
menu();
break;
case '3':
menu3();
break;
case '4':
if (FRN() == 0)
{
Change();
}
else
{
system("cls");
gotoxy(30, 13); printf("还没添加一本图书信息呢,先去添加一本吧!");
}
gotoxy(30, 15); printf("按任意键返回主界面!");
getch();
menu();
break;
case '5':
menu5();
break;
case '6':system("cls"); exit(0); break;
default: menu();
}
}
void menu5()
{
system("cls");
if (FRN() == 0)
{
PXJM();
char c;
c = getch();
switch (c)
{
case '1':
FileRead(head);
PX_b(head);
output(head);
gotoxy(30, 25); printf("按任意键返回浏览界面!");
getch();
menu5();
break;
case '2':
FileRead(head);
PX_p(head);
output(head);
gotoxy(30, 25); printf("按任意键返回浏览界面!");
getch();
menu5();
break;
case '3':
menu();
break;
default:menu5();
}
}
else
{
system("cls");
gotoxy(30, 23); printf("还没添加一本图书信息呢,先去添加一本吧!");
gotoxy(30, 25); printf("按任意键返回主界面!");
getch();
menu();
}
}
void menu3()
{
system("cls");
if (FRN() == 0)
{
DelJM();
char c;
c = getch();
switch (c)
{
case '1':
system("cls");
FileRead(head);
DelWriter(head);
system("cls");
gotoxy(30, 23); printf("按任意键返回删除菜单!");
getch();
menu3();
break;
case '2':
system("cls");
FileRead(head);
DelBook(head);
gotoxy(30, 24); printf("按任意键返回删除菜单!");
getch();
menu3();
break;
case '3':
menu();
break;
default:menu3();
}
}
else
{
system("cls");
gotoxy(30, 23); printf("还没添加一本图书信息呢,先去添加一本吧!");
gotoxy(30, 25); printf("按任意键返回主界面!");
getch();
menu();
}
}
int ReCheck(char str[])
{
if (FRN() == 0)
{
struct BOOK* Head = (struct BOOK*)malloc(sizeof(struct BOOK));
Head->next = NULL;
FileRead(Head);
struct BOOK* q = (struct BOOK*)malloc(sizeof(struct BOOK));
q = Head;
while (q->next != NULL)
{
if (strcmp(str, q->next->ISBN) == 0)
{
return -1;
}
q = q->next;
}
return 0;
}
else
{
return 0;
}
}
GPT3.5的回答
是的,当C语言输出的信息太多时,也可能会导致输出的格式排版错误。这通常是因为输出的信息中包含了太多的空格或制表符,或者因为输出的信息没有按照正确的格式进行排列。
为了避免这种情况,可以尝试以下几种方法:
使用换行符"\n"来结束每行输出,这样可以确保每行输出都是独立的。
使用printf()函数中的格式控制符来控制输出的格式,例如"%d"表示输出整数,"%f"表示输出浮点数等。
使用printf()函数中的格式控制符来设置输出的字段宽度和精度,这样可以确保每个字段的宽度和精度都是相同的。
尽可能地避免在输出中使用过多的空格或制表符。
将输出分成多个部分,每个部分都按照正确的格式进行排列,然后再将它们组合在一起输出。
通过使用这些方法,可以确保C语言输出的信息始终按照正确的格式进行排列,避免出现格式排版错误的问题。
全局变量是整个程序都可访问的变量,谁都可以访问,生存期在整个程序从运行到结束(在程序结束时所占内存释放);
而局部变量存在于模块(子程序,函数)中,只有所在模块可以访问,其他模块不可直接访问,模块结束(函数调用完毕),局部变量消失,所占据的内存释放。
操作系统和编译器,可能是通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载.局部变量则分配在堆栈里面。