// 商品信息管理.cpp : 定義控制台應用程序的入口點。
//
// 小型商品信息管理系統.cpp : 定義控制台應用程序的入口點。
//
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<fstream>
#include<string>
#include<conio.h>
#include<iostream>
#include<sstream>
using namespace std;
//定義結構體
typedef struct goods{
string name;//商品名
string number;//商品編號
string area_of_producting;//出產地
string the_date_of_purchase;//進貨日期
string sales_man;//進貨商
int price;//商品單價
int stocks;//庫存量
struct goods *next;
int i;//記錄商品原始節點位置
goods() {//構造函數
name="\0";
number="\0";
area_of_producting="\0";
the_date_of_purchase="\0";
sales_man="\0";
price=0;
i=0;
next=NULL;
}
}Goods;
//函數聲明
Goods* Search_the_massage_of_Goods(Goods* );
Goods* Delete_link_node(Goods *);
Goods* Insert_link_node(Goods*);
Goods* Create_link_node(Goods* );
Goods* Create_head();
void Input_the_massage_of_Goods(Goods *);
Goods* Sort_link_node(Goods *);
void Write_the_massage_of_one_Good_to_file(Goods *);
Goods* Read_the_massage_of_Goods_from_system();
//主函數
int main(){
while(1){
char ch='0';
Goods *p,*pr;
system("color A9");
cout<<"_____________________________________________\n";
cout<<(char)2<<"輸入相應數字執行相應操作."<<(char)2<<"\n";
cout<<"1.錄入商品信息"<<(char)2<<"\n";
cout<<"2.刪除商品信息"<<(char)2<<"\n";
cout<<"3.查詢商品信息"<<(char)2<<"\n";
cout<<"4.修改商品信息"<<(char)2<<"\n";
cout<<"5.插入商品信息"<<(char)2<<"\n";
cout<<"6.退出"<<(char)2<<"\n";
cout<<"_____________________________________________\n";
Goods *head=Read_the_massage_of_Goods_from_system();;
if(head==NULL){
head=Create_head();
}
for(;ch>'6'|| ch<'1';ch=_getch());
system("cls");
switch(ch){
case '1':
p=Create_link_node(head);
cout<<"是否立即寫入商品信息 Y/N\n";
char ch;
for(;ch!='Y'&&ch!='y'&&ch!='N'&&ch!='n';ch=_getch());
if(ch=='y'||ch=='Y') Input_the_massage_of_Goods(p);
Write_the_massage_of_one_Good_to_file(p);//將信息寫入文件
break;
case '2':
Delete_link_node(head);
break;
case '3':
Search_the_massage_of_Goods(head);
break;
case '4':
cout<<"查詢要修改的商品\n";
pr=Search_the_massage_of_Goods(head);
Input_the_massage_of_Goods(pr);
break;
case '5':
Insert_link_node(head);
break;
case '6':
exit(0);
break;
}
}
return 0;
}
Goods* Delete_link_node(Goods *head){
Goods *p,*pr;
cout<<"查詢要刪除的節點\n";
p=Search_the_massage_of_Goods(head);
if(p==head){
p=head;
head=p->next;
free(p);
}
else if(p->next=NULL){
for(pr=head;pr->next!=p;pr=pr->next);
free(pr);
pr=NULL;
p=NULL;
}
else{
for(pr=head;pr->next!=p;pr=pr->next);
pr->next=p->next;
free(p);
p=NULL;
}
return head;
}
//創建頭節點,返回頭節點的指針
Goods* Create_head(){
Goods *head;
head=new Goods();
head->i=1;
head->next=NULL;
return head;
}
//新建節點,傳入頭指針,如果頭指針為空,將新建節作為頭節點,否則將新建節
//插入至鏈表末尾,返回頭指針
Goods* Create_link_node(Goods* head){
Goods *p,*pr;
p=new Goods();
(p->i)++;
if(head==NULL){
head=p;
}
else{
for(pr=head;pr->next!=NULL;pr=pr->next);
pr->next=p;
}
return head;
}
//新建節點,傳入頭指針,調用查詢函數,插入節點至查詢到的函數的前一節點
Goods* Insert_link_node(Goods*head){
Goods *pr,*p,*temp;
p=new Goods();
if(p==NULL)
{
cout<<"No enough mrmory!\n";
exit(0);
}
p->next=NULL;
if(head==NULL)
head=p;
else
{
cout<<"插入節點至查詢到的函數的前一節點\n";
pr=Search_the_massage_of_Goods(head);
if(pr==head)
{
p->next=head;
head=p;
}
else
{
for(temp=head;temp->next==pr;temp=temp->next);
p=temp->next;
pr=p->next;
}
}
return head;
}
//傳入頭指針,調用查詢函數,查詢相應要刪除的節點,返回頭指針
Goods* Search_the_massage_of_Goods(Goods* head){
Goods* p;
while(1){
cout<<"__________________________________________\n";
cout<<"輸入相應數字執行相應查詢操作 \n";
cout<<"1.按商品名查詢\n";
cout<<"2.按商品編號查詢\n";
cout<<"按其余任意鍵退出\n";
cout<<"__________________________________________\n";
string s;
char ch;
for(;ch!='1'&&ch!='2'&&ch!='*';ch=_getch());
switch(ch){
case '1':
cout<<"請輸入要查詢的商品名";
cin>>s;
for(p=head;s!=p->name;p=p->next);
if(p==NULL) {
cout<<"未查找到\n";
break;
}
else
cout<<"商品名"<<p->name<<"商品編號"<<p->number<<"出產地"<<p->area_of_producting<<"進貨商"<<p->sales_man<<"庫存量"<<"進貨日期"<<p->stocks<<p->the_date_of_purchase;
break;
case '2':
cout<<"請輸入要查詢的商品編號";
cin>>s;
for(p=head;s!=p->number;p=p->next);
if(p==NULL) {
cout<<"未查找到\n";
break;
}
else
cout<<"商品名"<<p->name<<"商品編號"<<p->number<<"出產地"<<p->area_of_producting<<"進貨商"<<p->sales_man<<"庫存量"<<"進貨日期"<<p->stocks<<p->the_date_of_purchase;
break;
default:
goto a;
break;
}
}
a:;
return p;
}
void Input_the_massage_of_Goods(Goods *p){
cout<<"請輸入商品編號";
getline(cin,p->number);
cout<<"請輸入商品名稱";
getline(cin,p->name);
cout<<"請輸入商品出產地";
getline(cin,p->area_of_producting);
cout<<"請輸入商品進貨日期,中間用‘-’隔開";
getline(cin,p->the_date_of_purchase);
cout<<"請輸入商品進貨商";
getline(cin,p->sales_man);
cout<<"請輸入商品庫存量";
cin>>p->stocks;
cout<<"請輸入商品單價";
cin>>p->price;
system("cls");
}
//排序函數,傳入節點頭指針,該函數要實現按商品單價排序和按商品庫存量排序返回頭指針
Goods* Sort_link_node(Goods *head){
return head;
}
//輸入函數,將商品信息存儲到文件中,便於下次文件的初始化讀寫,傳入新建節點的指針,將其內容寫入文件末尾
void Write_the_massage_of_one_Good_to_file(Goods *p){
ofstream file("the_massage_of_Goods.txt",ios::out|ios::ate);
//)用 ate 方式打開一個已存在的文件,文件指針自動移到文件末尾,數據可以寫入到其中。
//用 in 方式打開文件只能用於輸入數據,而且該文件必須已經存在
if(!file){//如果文件不存在
cout<< "不可以打開文件"<<endl;
exit(1);
}
//寫文件
file<<p->i<<p->name<<p->number<<p->sales_man<<p->stocks<<p->area_of_producting<<p->price<<p->stocks<<'\n';
//關閉文件
file.close();
}
//在程序打開時將信息從文件讀入,初始化信息
Goods* Read_the_massage_of_Goods_from_system(){
Goods *p,*head=Create_head();
ifstream rfile("the_massage_of_Goods.txt",ios::in); //in 方式打開文件只能用於輸入數據,而且該文件必須已經存在
if(!rfile){
cout<< "不可以打開文件"<<endl;
exit(1);
}
string str;
for(p=head;getline(rfile,str);p=p->next){
istringstream sin(str);
p=new Goods();
sin>>p->i>>p->name>>p->number>>p->sales_man>>p->stocks>>p->area_of_producting>>p->price>>p->stocks;
}
//rfile.close();
return head;
}
這看上去好像是沒什莫問題,可是在VS2008運行時,控制台一閃而過,,這是為甚末呢??小編也是苦思良久,終於得出答案,用 in 方式打開文件只能用於輸入數據,而且該文件必須已經存在,所以我就在源文件出建立了the_massage_of_Goods.txt這個文件,可問題並沒有解決,最後,小編在Goods* Read_the_massage_of_Goods_from_system()這個函數裡加上了_getch();
Goods* Read_the_massage_of_Goods_from_system(){
Goods *p,*head=Create_head();
ifstream rfile("the_massage_of_Goods.txt",ios::in); //in 方式打開文件只能用於輸入數據,而且該文件必須已經存在
_getch();
if(!rfile){
cout<< "不可以打開文件"<<endl;
exit(1);
}
string str;
for(p=head;getline(rfile,str);p=p->next){
istringstream sin(str);
p=new Goods();
sin>>p->i>>p->name>>p->number>>p->sales_man>>p->stocks>>p->area_of_producting>>p->price>>p->stocks;
}
//rfile.close();
return head;
}
這時控制台終於停了下來,顯示一個我設計的一個菜單界面
可只要按一下,控制台又會消失,到底是哪出了問題呢??經過一再的檢查代碼,終於發現是這裡:
只能說是文件沒有成功打開,接下來我們可以試試,我對Goods* Read_the_massage_of_Goods_from_system()函數做以下修改,如果文件打開失敗,那末就會打出一連串#字符號並顯示不可打開文件:
Goods* Read_the_massage_of_Goods_from_system(){
Goods *p,*head=Create_head();
ifstream rfile("the_massage_of_Goods.txt",ios::in); //in 方式打開文件只能用於輸入數據,而且該文件必須已經存在
if(!rfile){
cout<< "不可以打開文件"<<endl;
cout<<"#################################################";
_getch();
exit(1);
}
string str;
for(p=head;getline(rfile,str);p=p->next){
istringstream sin(str);
p=new Goods();
sin>>p->i>>p->name>>p->number>>p->sales_man>>p->stocks>>p->area_of_producting>>p->price>>p->stocks;
}
//rfile.close();
return head;
}
運行後發現:
很明顯,文件打開失敗了,這又是怎末回事呢??
一般操作系統都會隱藏文件後綴,如果設置了隱藏常見文件類型,就會有兩個後綴,所以就只能檢測文件是否存在了,如果不存在,則重新創建一個,於是小編對Goods* Read_the_massage_of_Goods_from_system()作了如下修改:
//在程序打開時將信息從文件讀入,初始化信息
Goods* Read_the_massage_of_Goods_from_system(){
if(exist("the_massage_of_Goods.txt")==0) {
ifstream rfile("the_massage_of_Goods.txt",ios::out);
rfile.close();
} //如果文件不存在,則重新創建一個文件
Goods *p,*head=Create_head();
ifstream rfile("the_massage_of_Goods.txt",ios::in); //in 方式打開文件只能用於輸入數據,而且該文件必須已經存在
if(!rfile){
cout<< "不可以打開文件"<<endl;
exit(1);
}
string str;
for(p=head;getline(rfile,str);p=p->next){
istringstream sin(str);
p=new Goods();
sin>>p->i>>p->name>>p->number>>p->sales_man>>p->stocks>>p->area_of_producting>>p->price>>p->stocks;
}
rfile.close();
return head;
}
int exist(char *file) //傳入想要判斷的路徑字符串指針
{
FILE *fp;
fp=fopen(file,"r"); //fopen是一個C庫函數,用於打開文件,"r"是只讀模式,在這種模式下,如果文件存在,則能成功以只讀模式打開,fopen返回一個非0的文件描述符,如果文件不存在,則fopen返回NULL(NULL意思是空)。正好可以利用這一點來判斷文件是否存在
if(fp=NULL)
return 0; //不存在返回0
else
{
fclose(fp); //存在的話,要先把之前打開的文件關掉
return 1; //然後返回1
}
}
最終調試成功,謝謝諸位。。。