1. 程式人生 > >南郵2015年程式設計周_個人股票資訊管理系統

南郵2015年程式設計周_個人股票資訊管理系統

個人股票管理系統

一、 課題內容和要求

【問題描述】                              

該系統要求建立一個時間段內某股民的投資情況管理系統,並具有排序、查詢、計算、顯示等功能。通過此課題,熟練掌握檔案、陣列、指標的各種操作,以及一些演算法思想的應用。

【功能要求】

(1)股票賬戶資訊應包括:股票程式碼,股票名稱,持倉數目,當前價,漲跌幅,浮動盈虧,賬戶總值,剩餘資金等。

(2)需要實現的功能

1) 建立10支給定股票的資訊結構陣列,包括股票程式碼,股票名稱,當前價,漲跌幅等。並在統計的時間段以當天的收盤價作為每隻股票的當前價進行資訊更新和顯示

2) 實現使用者的投資過程,記錄買賣過程(通過持倉數目的變化顯示)

3) 每天更新和顯示使用者的賬戶資訊

4) 計算並顯示給定時間段內的盈虧

5) 按盈虧大小進行排序

6) 按股票程式碼查詢該股票的價格變化

7) 查詢收益最大的股票程式碼

8) 將該時間段內每天的賬戶資訊內容存為檔案。

(3)介面友好,輸入資訊符合邏輯如股票買入數目必須為100的整數倍,剩餘資金不能為負數、不可能有非數字的字元等。

一、 需求分析

(1)提供可操作的主選單:輸出主選單,用於顯示以從檔案中載入的總客戶資訊和若干個可選的功能選項。根據客戶輸入的選項來執行不同的功能,執行不同的函式。

(2)進行文字資訊的載入:可選擇顯示或輸入股票資訊。

(3)交易功能:通過持倉數目和當前價的變化顯示記錄買賣過程,實現使用者投資過程。

4)查詢資訊功能:查詢價格變化,查詢當前時間收益最大的股票並輸出其資訊。

5)計算資訊功能:計算某隻股票的盈虧,進行盈虧排序。

6)更改資訊功能:重新輸入某隻股票的資訊,以防止初次輸入錯誤。

7)存檔功能:將當前的操作結果存入文件。

8)清屏功能:將當前顯示框中的內容清除。

三、概要設計 

1 主要類

class Stock                   //股票類

{

private:

int count; //持倉數

double price; //當前價

double fall_rise; //漲幅;

double profit; //浮動盈虧

double total_value; //單隻股票總值

char name[20]; //股票名稱

char number[20]; //股票程式碼

public:

Stock(); //建構函式

void Create(); //建立Stock類的物件

double Get_profit(); //提取並返回成員變數profit

double Get_price(); //提取並返回成員變數price

char * Get_number(); //提取並返回成員變數number

double Get_Total(); //提取並返回成員變數total_value

void operator =(Stock &s); //過載“=”運算子

void Busines(); //進行買賣交易的函式

double Profit_Rise(); //提取並返回浮動盈虧

void Update(); //更新資訊

};

class StockManage       //股票管理系統類

{

private:

Stock stock[10]; //定義Stock類的物件

double total_surplus;       //剩餘金額

double total_stock;         //十隻股票的總值

void MaxProfit()    //計算最大盈利

void change();            //更新模組

void Search()             //按照股票程式碼檢視價格變化 按照天數

void Sort();    //盈利排序 原函式在源資料上操作,改為操作臨時陣列;不能改變原資料

bool getInfo(char * filename,int n,Stock stock[])//讀取資訊,(檔名字,結構體個數,要輸入的stock,)

bool putInfo(char * filename,int n,Stock stock[])//寫入資訊,將資訊讀到陣列stock

public :

StockManage()            //建構函式

void menu(); //顯示選單

void show();              //顯示/輸入資訊模組

void operate(Stock &stock); //操作交易模組

void query();              //查詢模組

void calculate();         //計算模組

void saveFile(int year ,int month,int day,int n,Stock stock[]);//存檔

void getFile(int year,int month,int day,int n,Stock stock[]) ;//讀檔

void run();      //執行管理系統

};

Main函式:
#include"StockManage.h"
int main()
{
    system("color F1");                    //更改介面顏色 
    StockManage manage;                  //建立股票管理類物件manage
    manage.run();                         //呼叫函式run
    return 0;
}
#ifndef INCLUDE_STOCK_H_
#define INCLUDE_STOCK_H_
#endif
Stock.h檔案:
#include <iostream>
#include <iomanip>
#include<cstdlib>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
class Stock                      //股票類
{
private:
	int count;                   //持倉數
	double price;                //當前價
	double fall_rise;            //漲幅
	double profit;               //盈虧
	double total_value;          //單隻股票總值
	char name[20];               //股票名稱
	char number[20];             //股票程式碼
public:
	Stock();                     //建構函式
	void Create();               //建立股票資訊
	double Get_profit();         //返回盈虧
	double Get_price();          //返回當前價
	char * Get_number();         //返回股票程式碼
	char * Get_name();           //返回股票名稱
	double Get_Total();          //返回單隻股票總值
	void operator =(Stock &s);   //過載運算子
	void Busines();              //進行股票交易
	double Profit_Rise();        //計算浮動盈利函式
	void Update();               //更新顯示個人股票資訊
};

Stock::Stock()                           //建構函式
{
	strcpy(number,"000");
	strcpy(name,"000");
	count=0.0;
	price=0;
	fall_rise=0;
	profit=0;
	total_value=0;
}

void Stock::Create()                      //建立股票資訊
{
	cout<<"請輸入股票程式碼(用數字表示)"<<endl;
	cin>>number;
	cout<<"請輸入股票名稱"<<endl;
	cin>>name;
	cout<<"請輸入當前價"<<endl;
	cin>>price;
	cout<<"請輸入持倉數"<<endl;
	cin>>count;
}

double Stock::Get_Total()     //返回單隻股票總值
{
	return total_value;
}

double Stock::Get_profit()    //返回盈利
{
	return profit;
}

char *Stock::Get_number()    //返回股票程式碼
{
	return number;
}

char *Stock::Get_name()    //返回股票名稱
{
	return name;
}

double Stock::Get_price()      //返回當前價
{
	return price;
}

void Stock::operator =(Stock &s)  //過載 =運算子 使兩個股票類物件之間可以進行賦值
{
	strcpy(number,s.number);
	strcpy(name,s.name);
	count=s.count;
	price=s.price;
	fall_rise=s.fall_rise;
	profit=s.profit;
	total_value=s.total_value;
}

//輸出股票基本資訊
void Stock::Update()     //更新顯示股票資訊
{
    cout<<setw(10)<<left<<number;              //域寬為10,左對齊,保證格式一致
	cout<<setw(10)<<left<<name;
    cout<<setw(10)<<left<<price;
    cout<<setw(10)<<left<<count;
    cout<<setw(10)<<left<<fall_rise;
    cout<<setw(10)<<left<<profit;
    cout<<setw(10)<<left<<total_value<<endl;
}

void Stock::Busines()          //記錄買賣過程,進行股票交易
{
	int num,k=1;
	double p;
	cout<<"請輸入買入(售出)股票數目:"<<endl;
	cout<<"注:買入股票數目只能為100的整數倍"<<endl;
	do
	{
		cin>>num;
		k=1;
		if(num>0)
		{
			if(num%100!=0)
			{
				cout<<"輸入錯誤,買入股票數目只能為100的整數倍。"<<endl;
				k=0;
			}
		}
		else
		{
			if(-num>count)
			{
				cout<<"輸入錯誤,售出股票數目不能大於已持股票數目。"<<endl;
				k=0;
			}
		}
	}while(k==0);
	cout<<"請輸入買入(售出)價格:"<<endl;
	cin>>p;
	count=count+num;
	fall_rise=p-price;
	profit=fall_rise*num-(num*p*0.0003+num*p*0.0003);/*買入num股之後的盈利*/
	price=p;
	total_value=count*price;
}

double Stock::Profit_Rise()      //計算浮動盈虧
{
    return profit;
}
StockManage.h檔案:
#include"stock.h"
class StockManage                //股票管理系統類
{
private:
    Stock stock[10];             //股票類物件陣列
	double total_stock;           //總值
	double total_surplus;         //剩餘金額
    void MaxProfit();            //計算最大盈利
    void Search();               //按照股票程式碼檢視價格變化(按照天數)
    void Sort();                 //盈利排序(原函式在源資料上操作,改為操作臨時陣列;不能改變原資料)
    bool getInfo(char * filename,int n,Stock stock[]);//讀取資訊 (檔名字,結構體個數,要輸入的stock)
    bool putInfo(char * filename,int n,Stock stock[]);//寫入資訊,將資訊讀到陣列stock裡
public :
    StockManage();                     //建構函式
    void menu();                       //顯示選單
    void show() ;                       //顯示/輸入資訊模組
    void operate(Stock &stock);           //操作交易模組
    void query();                       //查詢模組
    void calculate();                    //計算模組
	void change();                      //更新模組
    bool saveFile(int year ,int month,int day,int n,Stock stock[]);//存檔
    bool getFile(int year,int month,int day,int n,Stock stock[]); //讀檔
    void run();                         //執行管理系統
};

StockManage::StockManage()           //建構函式
{
	total_stock=0;
	total_surplus=100000;
}
 
void StockManage::Search()             //按照股票程式碼檢視價格變化 按照天數
{
	char num[20];
	int i;
	char choise;
	int flag=0;
	do
	{
		cout<<"請輸入股票程式碼:\n";
        cin>>num;        
		for(i=0;i<10;i++)
        {
			flag=0;
            if(strcmp(num,stock[i].Get_number())==0)
            {
				flag=1;
				cout<<"請核對股票名稱"<<endl;
				cout<<stock[i].Get_name()<<endl;
				cout<<"請核對資訊是否正確,若資訊正確請輸入t,若錯誤請輸入f。"<<endl;
				cin>>choise;
				if(choise=='f')
				{
					cout<<"資訊錯誤"<<endl;
					cout<<"查詢失敗"<<endl;
					return ;
				}
                break;
            }
        }
        if(flag==0)
        {
			cout<<"抱歉,這隻股票不存在,請重新輸入:"<<endl;
        }
	}while(flag==0);
    cout<<"請輸入你想要查詢起始的時間段(年/月/日/之間以空格隔開)"<<endl;
    int day1,day2,month1;
	int month2,year1,year2;
	cout<<"請輸入時間起點:\n";
	cout<<"請輸入起點年份:"<<endl;
	cin>>year1;
	cout<<"請輸入起點月份:(請以兩位數輸入01-12之間的數字)"<<endl;
	cin>>month1;
	cout<<"請輸入起點日期:(請以兩位數輸入01-31之間的數字)"<<endl;
	cin>>day1;
	cout<<"請輸入時間終點:\n";
	cout<<"請輸入終點年份:"<<endl;
	cin>>year2;
	cout<<"請輸入終點月份:(請以兩位數輸入01-12之間的數字)"<<endl;
	cin>>month2;
	cout<<"請輸入終點日期:(請以兩位數輸入01-31之間的數字)"<<endl;
	cin>>day2;
    Stock temp[10];
    getFile(year1,month1,day1,10,temp);     //讀檔
	cout<<"股票"<<temp[i].Get_number()<<"  "<<temp[i].Get_name()<<"在"<<year1<<"-"<<month1<<"-"<<day1<<"的價格為"<<temp[i].Get_price()<<endl;
	getFile(year2,month2,day2,10,temp);     //讀檔
    cout<<"股票"<<temp[i].Get_number()<<"  "<<temp[i].Get_name()<<"在"<<year2<<"-"<<month2<<"-"<<day2<<"的價格為"<<temp[i].Get_price()<<endl;
}

void StockManage::Sort()   //盈利排序 原函式在源資料上操作,改為操作臨時陣列;不能改變原資料
{
	Stock q;
    Stock temp[10];             //臨時陣列
	for(int j=0;j<10;j++)
    {
		temp[j]=stock[j];
	}
    for(int i=0;i<10;i++)         //進行氣泡排序
	{
		for(int j=i+1;j<10;j++)
		{
			if(temp[i].Get_profit()>temp[j].Get_profit())
            {
				q=temp[i];
                temp[i]=temp[j];
                temp[j]=q;
            }
        }
    }
	cout<<"股票程式碼  "<<"股票名稱  "<<"價格      ";
	cout<<"持倉數    "<<"漲幅      "<<"盈虧      ";
	cout<<"總值      "<<endl;
	for(int k=0;k<10;k++)
    {
		temp[k].Update();
    }
}

bool StockManage::getInfo(char * filename,int n,Stock stock[])//讀取資訊,(檔名字,結構體個數,要輸入的stock,)
{
	FILE * file=fopen(filename,"rb");
    if(file==NULL)
    {
		cout<<"開啟檔案:"<<filename<<"失敗!"<<endl;
        return false;
    }
    else
    {
		fread(stock,sizeof(Stock),n,file);          //塊資料讀取
        fclose(file);
        return true;
    }
}

bool StockManage::putInfo(char * filename,int n,Stock stock[])//寫入資訊,將資訊讀到陣列stock裡
{
	FILE * file=fopen(filename,"wb");
    if(file==NULL)
    {
		cout<<"開啟檔案:"<<filename<<"失敗!"<<endl;
        return false;
    }
    else
    {
		fwrite(stock,sizeof(Stock),n,file);                    //塊資料寫入
		fclose(file);
		return true;
    }
}

void StockManage::menu()                                //顯示主選單
{
	cout<<"               "<<"====================================="<<endl;
	cout<<"               "<<"====================================="<<endl;
	cout<<"               "<<"            個人股票管理系統         "<<endl;
    cout<<"               "<<"1----------顯示/輸入股票資訊---------"<<endl;
    cout<<"               "<<"2---------------交易-----------------"<<endl;
    cout<<"               "<<"3---------------查詢資訊-------------"<<endl;
    cout<<"               "<<"4---------------計算資訊-------------"<<endl;
	cout<<"               "<<"5---------------更改資訊-------------"<<endl;
    cout<<"               "<<"6---------------存檔-----------------"<<endl;
    cout<<"               "<<"7---------------退出-----------------"<<endl;
	cout<<"               "<<"8---------------清屏-----------------"<<endl;
	cout<<"               "<<"====================================="<<endl;
	cout<<"               "<<"====================================="<<endl;
}

void StockManage::show()                        //顯示/輸入股票資訊模組
{
	char p_t;
	int j=0;
	bool judge_file=true;
	do                     //選擇進行建立還是進行檢視功能
	{
		cout<<"輸入t建立股票資訊"<<endl;
		cout<<"輸入p檢視股票資訊"<<endl;
		cout<<"請輸入您想檢視的資訊的日期(t/p):"<<endl;
		cin>>p_t;
	}while (!(p_t =='p' || p_t== 't'));
	if(p_t=='p')
	{
		int day,month,year;
        cout<<"請輸入您想檢視的日期:"<<endl;
		cout<<"請輸入年份"<<endl;
        cin>>year;
		cout<<"請輸入月份"<<endl;
		cin>>month;
		cout<<"請輸入日期"<<endl;
		cin>>day;
        if(!getFile(year,month,day,10,stock))
		{
			judge_file=false;
		}
	}
	else
    {
		for(int i=0;i<10;i++)
        {
			stock[i].Create();
        }
    }
	if(judge_file==true)
	{
		cout<<"股票程式碼  "<<"股票名稱  "<<"價格      ";
	    cout<<"持倉數    "<<"漲幅      "<<"盈虧      ";
    	cout<<"總值      "<<endl;
        for(int i=0;i<10;i++)
		{
			stock[i].Update();
		}
	    cout<<endl;
	    for(j=0;j<10;j++)
		{
			total_stock+=stock[j].Get_Total();
		}
	    total_surplus=100000-total_stock;
    	cout<<"股票總值為:"<<total_stock<<endl;
	    cout<<"剩餘金額為:"<<total_surplus<<endl;
	}
}
void StockManage::operate(Stock &stock)                                   //操作交易模組
{
	stock.Busines();
}

void StockManage::query()                                                 //查詢模組
{
	cout<<"1------------股票價格變化---------------"<<endl;
	cout<<"2------------查詢收益最大的股票---------"<<endl;
    int choose;
    cout<<"請選擇操作項前的數字:"<<endl;
    cin>>choose;
    switch(choose)
    {
	case 1:
		Search();
		break;
	case 2:
        MaxProfit();
        break;
    }
}
    
void StockManage::calculate()                                            //計算模組
{
	cout<<"1--------------計算盈虧----------------"<<endl;
	cout<<"2------------計算盈虧排序--------------"<<endl;
    int choose,i;
	cout<<"請選擇操作項前的數字:"<<endl;
    cin>>choose;
    switch(choose)
    {
	case 1:
		for(i=0;i<10;i++)
        {
			cout<<"股票 "<<stock[i].Get_number()<<stock[i].Get_name()<<"的收益為:"<<stock[i].Profit_Rise()<<endl;
        }
		break;
	case 2:
        Sort();
        break;
    }
}

void StockManage::change()                         //更新模組
{
	char num[20];
	cout<<"請輸入需要更改的股票程式碼:\n";
    cin>>num;
    int i;
    for(i=0;i<10;i++)
    {
		if(strcmp(num,stock[i].Get_number())==0)     //找到對應的股票
        {
			stock[i].Create();
			break;
		}
	}
	for(i=0;i<10;i++)
	{
		stock[i].Update();
	}
}

bool StockManage::saveFile(int year ,int month,int day,int n,Stock stock[])//存檔
{
	char filename[100];
    sprintf(filename,"stock%d-%d-%d.dat",year,month,day);
    if(putInfo(filename,n,stock))
    {
		cout<<"存檔成功"<<endl;
		return true;
    }
	return false;
}

bool StockManage::getFile(int year,int month,int day,int n,Stock stock[]) //讀檔
{
	char filename[100];
	sprintf(filename,"stock%d-%d-%d.dat",year,month,day);
	if(getInfo(filename,n,stock))
    {
		cout<<"讀檔成功"<<endl;
		return true;
    }
	return false;
}

void StockManage::run()      //執行管理系統
{
	int k=0;
	double to=0,su=0;
    bool run=true;
    while(run==true)
    {
		Stock temp[10];
        menu();
        int choose;
        cout<<"請選擇操作項前的數字:"<<endl;
        cin>>choose;
        switch(choose)
        {
		case 1:
			show();
            break;
        case 2:
            char response;
			int i,j;
            do
            {
				k=0;
				to=0;
                cout<<"請輸入股票程式碼:"<<endl;
                char n[20];
                cin>>n;
				for(i=0;i<10;i++)
				{
					if(strcmp(n,stock[i].Get_number())==0)
					{
						k=1;
						break;
					}
				}
				if(k==0)
                {
					cout<<"抱歉,這隻股票不存在,請重新輸入:"<<endl;
                }
                else                              //找到股票後進行操作
                {
					for(j=0;j<10;j++)               //對temp進行賦值,保證原資料的安全性
					{
						temp[j]=stock[j];
					}
					operate(temp[i]);
					for(j=0;j<10;j++)
					{
						to+=temp[j].Get_Total();
					}
					su=100000-to;
					if(su<=0)
					{
						cout<<"交易金額已超出剩餘金額"<<endl;
					}
					else
					{
						for(j=0;j<10;j++)
						{
							stock[j]=temp[j];
						}
					}
                    cout<<"是否還需要進行交易(y/n)"<<endl;
                    cin>>response;
				}
			}while(response=='y'||response=='Y'|| k==0);
			total_stock=0;
			cout<<"股票程式碼  "<<"股票名稱  "<<"價格      ";
			cout<<"持倉數    "<<"漲幅      "<<"盈虧      ";
			cout<<"總值      "<<endl;
            for(i=0;i<10;i++)
			{
				total_stock+=stock[i].Get_Total();
                stock[i].Update();
			}
		    cout<<endl;
			total_surplus=100000-total_stock;
			cout<<"股票總值為:"<<total_stock<<endl;
			cout<<"剩餘金額為:"<<total_surplus<<endl;
            break;
		case 3:
			query();
            break;
        case 4:
            calculate();
            break;
		case 5:
			change();
			break;
        case 6:
			cout<<"請輸入年份"<<endl;
            int day,year,month;
            cin>>year;
			cout<<"請輸入月份"<<endl;
			cin>>month;
			cout<<"請輸入日期"<<endl;
			cin>>day;
            saveFile(year,month,day,10,stock);
			break;
		case 7:
			run=false;                    //退出系統
            break;
		case 8:
			system("cls");                 //清屏功能
			break;
		}
	}
}
     
void StockManage::MaxProfit()               //計算最大盈利
{
	int max=0;
    for(int i=1;i<10;i++)
    {
		if(stock[max].Get_profit()<stock[i].Get_profit())
        {
			max=i;
		}
	}
	cout<<"收益最大的股票程式碼為"<<endl;
    cout<<stock[max].Get_number()<<endl;
	cout<<"收益最大的股票名稱為"<<endl;
	cout<<stock[max].Get_name()<<endl;
}