笔记要点:
1。个人工具包samsTools 工具之一PromptMessage,方法:
pause():Console 下暂停命令;
showMessage:MS MessageBox/MessageBoxW 之D改写;
char askForChar(string msg=" ")从控制台读取用户输入并返回一字符串;
T askFor!(T)(string msg=" ") 从控制台读取用户输入并返回指定T类型值
1Console嵌套菜单的制作;
2。数据库OO数据类Sales;
3。std.stream顺序文件和随机文件读写操作。
PromptMessage.d:
module samsTools.PromptMessage; import std.c.windows.windows; import std.stdio; import std.string; import std.conv; enum MsgboxBtn { OK = 0x00000000, OKCancel = 0x00000001, AbortRetryIgnore = 0x00000002, YesNoCancel = 0x00000003, YesNo = 0x00000004, RetryCancel = 0x00000005, Default1 = 0x00000000, Default2 = 0x00000100, Default3 = 0x00000200, Default4 = 0x00000300 } enum MsgboxIcon { Hand = 0x00000010, Question = 0x00000020, Exclamation = 0x00000030, Asterisk = 0x00000040, //MB_USERICON = 0x00000080, Warning = MB_ICONEXCLAMATION, Error = MB_ICONHAND, Information = MB_ICONASTERISK, Stop = MB_ICONHAND } enum MagboxDefaultButton { Default1 = 0x00000000, Default2 = 0x00000100, Default3 = 0x00000200, Default4 = 0x00000300 } enum Misc { MB_APPLMODAL = 0x00000000, MB_SYSTEMMODAL = 0x00001000, MB_TASKMODAL = 0x00002000, MB_HELP = 0x00004000, // Help Button MB_NOFOCUS = 0x00008000, MB_SETFOREGROUND = 0x00010000, MB_DEFAULT_DESKTOP_ONLY = 0x00020000, MB_TOPMOST = 0x00040000, MB_RIGHT = 0x00080000, MB_RTLREADING = 0x00100000, MB_TYPEMASK = 0x0000000F, MB_ICONMASK = 0x000000F0, MB_DEFMASK = 0x00000F00, MB_MODEMASK = 0x00003000, MB_MISCMASK = 0x0000C000 } extern(Windows){int MessageBoxW(HWND,LPCWSTR,LPCWSTR,UINT);} int ShowMessage(in wstring msg,in wstring caption=r"Application", int style=MB_OK|MB_ICONINFORMATION) { return MessageBoxW(null,(msg~"\000").ptr,(caption~"\000").ptr,style); } alias ShowMessage showMessage; void pause(string msg=r"Press any key to continue...") { writefln("\n\n*******************************************************"); writefln("* %s *",msg); writefln("*******************************************************"); char[] input; readln(input); } char askForChar(string msg="") { string str="Please enter a char:"; write(msg.length==0?str:msg); char[] input; readln(input); char[] output=chomp(input); return (output.length>0)?output[0]:'0'; } T askFor(T)(string msg="") { static if(is(typeof(T[])==char[]) ||is(typeof(T[])==wchar[]) ||is(typeof(T[])==dchar[]) ||is(T==string)) { string str="a string:"; } /* else static if(is(typeof(T)==char) ||is(typeof(T)==wchar) ||is(typeof(T)==dchar)) { string str="a char:"; return to!(T)[0]; } */ else static if(is(T==int)) string str="Pleaes enter an integer:"; else static if(is(T==float)) string str="Pleaes enter a floating point number:"; else static if(is(T==double)) string str="Pleaes enter a double precision point number:"; else static if(is(T==ushort)||is(T==short)) string str="Pleaes enter a short integer:"; else static if(is(T==ulong)||is(T==long)) string str="Pleaes enter a very very long integer:"; else { //Stdout.format("Please enter a number:").flush: string str="Pleaes enter a number or string:"; } write(msg.length==0?str:msg); //Stdout.format("Please enter {}:",str).flush; try { char[] input; readln(input); return to!(T)(chomp(input)); } catch(Exception msg) { //Stdout("Invalid input").newline; writefln("Invalid input"); // return T.init; assert(0); } //assert(0); }
ledgerSys.d:
module ledgerSys; import std.stdio; import std.string; import std.conv; import std.file; import std.stream; import samsTools.PromptMessage; class Company { private: string companyName, companyOwner, companyAddress, companyCity, companyState, companyZip; public: string CompanyName() { return companyName; } string CompanyName(string companyName) { return this.companyName=companyName; } string CompanyOwner() { return companyOwner; } string CompanyOwner(string companyOwner) { return this.companyOwner=companyOwner; } string CompanyAddress() { return companyAddress; } string CompanyAddress(string companyAddress) { return this.companyAddress=companyAddress; } string CompanyCity() { return companyCity; } string CompanyCity(string companyCity) { return this.companyCity=companyCity; } string CompanyState() { return companyState; } string CompanyState(string companyState) { return this.companyState=companyState; } string CompanyZip() { return companyZip; } string CompanyZip(string companyZip) { return this.companyZip=companyZip; } public: void inputName() { CompanyName=askFor!(string)("What's your company's name?"); } string outputName() { return CompanyName; } void inputOwner() { CompanyOwner=askFor!(string)("Who is the company's owner? "); } void inputAddress() { CompanyAddress=askFor!(string)("What's the company's address? "); } void inputCity() { CompanyCity=askFor!(string)("What's the company's city? "); } void inputState() { CompanyState=askFor!(string)("What's the company's state? "); } void inputZip() { CompanyZip=askFor!(string)("What's the company's zip? "); } string CompanyInfo() { string info= "Company: "~CompanyName~"\n" ~"Owner: "~CompanyOwner~"\n" ~"Address: "~CompanyAddress~"\n" ~"City: "~CompanyCity~"\n" ~"State: "~CompanyState~"\n" ~"Zip: "~CompanyZip~"\n"; return info; } void outputCompanyInfo() { writefln(CompanyInfo); } string toString() { return CompanyInfo; } } class CDate { private: int month; int day; int year; public: this() { this(1,1,1000); } this(int month,int day,int year) { Month=month; Day=day; Year=year; } int Month() { return month; } int Month(int month) { return this.month=month; } int Day() { return day; } int Day(int day) { return this.day=day; } int Year() { return year; } int Year(int year) { return this.year=year; } public: void inputMonth() { month=askFor!(int)("What's the month? "); } void inputDay() { day=askFor!(int)("What's the day? "); } void inputYear() { year=askFor!(int)("What's the year? "); } int outputMonth() { return Month; } int outputDay() { return Day; } int outputYear() { return Year; } string dateInfo() { string strMonth=month<10?"0"~to!string(month):to!string(month); string strDay=day<10?"0"~to!string(day):to!string(day); string strYear=year<10?"200"~to!string(year):year<100?"20"~to!string(year):to!string(year); return strMonth~"/"~strDay~"/"~strYear; } string toString() { return dateInfo; } ref CDate parse(string strDate) { string[] result=split(strDate,"/"); this.month=to!(int)(result[0]); this.day=to!(int)(result[1]); this.year=to!(int)(result[2]); return this; } } class Sales:CDate { public static const string lineSep=" ,"; private: float[5] dailySales; float getDailySales() { char[] input; readln(input); return to!(float)(chomp(input)); } public: this() { super(); } void inputSalesAmounts() { for(int gl=3;gl<=7;++gl) { char resp; char ch; char[] input; do { writef("What's the sales for GL #%d?",gl); readln(input); dailySales[gl-3]=to!(float)(chomp(input)); write("Correct?(Y/N) "); readln(input); resp=chomp(input)[0]; }while((resp!='Y') && (resp!='y')); } } void modifySalesAmount(int number) { writefln("The current for GL account #%d is:%f", number,dailySales[number]); write("What shoud the amount be? "); dailySales[number]=getDailySales; } void showSalesAmounts() { float ttl_sales=0.00; for(int gl=3;gl<=7;++gl) { float amout=dailySales[gl-3]; writefln("\nSales GL #%d :%10.2f", gl,amout); ttl_sales+=amout; } writeln("--------------------------------------"); writefln("Total Sales %10.2f",ttl_sales); } float showSalesAmount(int number) { return dailySales[number]; } float[] DailySales() { return dailySales; } float[] DailySales(float[] dailySales) { return this.dailySales=dailySales; } string toString() { string result=""; result~=super.toString; foreach(amount;dailySales) result~=lineSep~std.string.format("%10.2f",amount/*to!string(amount*/); return result; } } void mainMenu() { char menu_1='0'; do { menu_1='0'; clr_scrn; char[] input; write(" Main Menu\n" " 1. Start New Client\n" " 2. Expense Ledger Menu\n" " 3. Sales Ledger Menu\n" " 4. Print P&L\n" " 5. End of Year Processing\n" " 6. Exit\n" " which? "); readln(input); menu_1=chomp(input)[0]; clr_scrn; switch(menu_1) { case '1': startClient; menu_1='0'; break; case '2': menu_1='0'; break; case '3': salesLedger; menu_1='0'; break; case '4': menu_1='0'; break; case '5': menu_1='0'; break; case '6': menu_1='6'; break; default: menu_1='0'; break; } }while(menu_1=='0'); } void clr_scrn() { for(int i=0;i<25;++i) writeln("\n"); } void salesLedger() { char menu_3='0'; char[] input; do { menu_3=0; clr_scrn; write( " Sales Ledger Menu\n" " 1. Enter Sales\n" " 2. Change Sales\n" " 3. Print Sales\n" " 4. End of Month Processing for Sales\n" " 5. Return to Main Menu\n" " which? "); readln(input); menu_3=chomp(input)[0]; switch(menu_3) { case '1': inputSales; menu_3='0'; break; case '2': editSales; menu_3='0'; break; case '3': printSales; menu_3='0'; break; case '4': eomSales; menu_3='0'; break; case '5': menu_3='5'; break; default: menu_3='0'; break; } }while(menu_3=='0'); } void inputSales() { char resp=' '; clr_scrn; Sales today=new Sales; std.stream.File outfile=new std.stream.File; outfile.open("SALES.DAT",FileMode.In|FileMode.Out|FileMode.Append); do { clr_scrn; today.inputDay; today.inputMonth; today.inputYear; today.inputSalesAmounts; outfile.writeLine(today.toString); write("Enter another day?(Y/N) "); resp=' '; char[] input; readln(input); resp=chomp(input)[0]; }while(resp=='Y'||resp=='y'); outfile.close; } void printSales() { std.stream.File output=new std.stream.File; output.open("SALES.DAT",FileMode.In); while(! output.eof) { string sofarRead=cast(string)output.readLine; string[] contents=split(sofarRead,Sales.lineSep); Sales sales=new Sales; sales.parse(contents[0]); float[] theDailySales; for(int i=1;i<contents.length;++i) theDailySales~= to!(float)(strip(contents[i])); sales.DailySales=theDailySales; writeln(sales.toString); } output.close; } void editSales() { version(Windows) { int caretLength="\b\n".length; } else { int caretLength="\n".length; } Sales today=new Sales; ulong last_record; long post; clr_scrn; int record_number; std.stream.File output=new std.stream.File; output.open("SALES.DAT",FileMode.Out|FileMode.In); if(!output.readable) writefln("The file is unreadable"); if(!output.writeable) writefln("The file is unwriteable"); if(!output.seekable) writefln("The file is unseekable"); if(!output.isOpen) writefln("The file is not open."); if(!output.eof) writefln("The file is not at EOF."); output.seekSet(0); int bytes_per_line=output.readLine.length+caretLength; writefln("The length of each line is %d bytes.",bytes_per_line); ulong end_position=output.seekEnd(0); last_record=end_position/bytes_per_line; writefln("The length of the file is %d bytes.",end_position); writefln("Total records:%d",last_record); if(last_record==0) { writefln("No records."); return ; } char resp=' '; do { do { record_number=askFor!(int)("Which record do you want to see?"); if(record_number>last_record||record_number<1) writefln("Beyond end of data.Pick another record."); }while( record_number>last_record || record_number<1); clr_scrn; writefln("You want to see record #%d",record_number); post=(record_number-1)* bytes_per_line; writefln("Current position:%d",output.position); output.seekSet(post); writefln("Current position:%d",output.position); writefln(output.readLine); writefln("Now will replace with new record:"); Sales newday=new Sales; newday.inputDay; newday.inputMonth; newday.inputYear; newday.inputSalesAmounts; output.seekSet(post); output.writeLine(newday.toString); writefln("Current position:%d",output.position); writefln("Record changed."); resp=askForChar("Do you want to edit another record? (Y/N)"); clr_scrn; }while(resp=='y'||resp=='Y'); output.close; } void eomSales() { } void startClient() { }
testcase.d //main module
module testcase; import ledgerSys; import std.stdio; import std.stream; import samsTools.PromptMessage; void testCompany() { Company IBM=new Company; IBM.CompanyName="IBM"; IBM.CompanyOwner="Liu Chuanzhi"; IBM.CompanyAddress="Beijing,China"; IBM.CompanyCity="Beijing"; IBM.CompanyState="P.R.China"; IBM.CompanyZip="100082"; IBM.outputCompanyInfo; IBM.CompanyCity=askFor!(string)("What's your favorite city then?"); IBM.CompanyState=askFor!(string)("What's your company State? "); writeln(IBM); IBM.inputAddress; writeln(IBM); } void testDate() { CDate today=new CDate; writeln(today); today.Month=7; today.Day=9; today.Year=2009; writeln(today); Sales sales=new Sales; sales.Day=today.Day; sales.Month=today.Month; sales.Year=today.Year; sales.inputSalesAmounts; writeln(sales); } void testParseDate() { CDate temp=new CDate; temp.parse("07/09/2009"); writeln(temp); writefln("Month=%d;Day=%d;Year=%d",temp.Month,temp.Day,temp.Year); } void testRecord() { version(Windows) { int caretLength="\b\n".length; } else { int caretLength="\n".length; } Sales today=new Sales; ulong last_record; long post; int record_number; std.stream.File output=new std.stream.File; output.open("SALES.DAT",FileMode.Out|FileMode.In); if(!output.readable) writefln("The file is unreadable"); if(!output.writeable) writefln("The file is unwriteable"); if(!output.seekable) writefln("The file is unseekable"); if(!output.isOpen) writefln("The file is not open."); if(!output.eof) writefln("The file is not at EOF."); output.seekSet(0); int bytes_per_line=output.readLine.length+caretLength; writefln("The length of each line is %d bytes.",bytes_per_line); ulong end_position=output.seekEnd(0); last_record=end_position/bytes_per_line; writefln("The length of the file is %d bytes.",end_position); writefln("Total records:%d",last_record); if(last_record==0) { writefln("No records."); return ; } char resp=' '; do { do { record_number=askFor!(int)("Which record do you want to see?"); if(record_number>last_record||record_number<1) writefln("Beyond end of data.Pick another record."); }while( record_number>last_record || record_number<1); writefln("You want to see record #%d",record_number); post=(record_number-1)* bytes_per_line; writefln("Current position:%d",output.position); output.seekSet(post); writefln("Current position:%d",output.position); writefln(output.readLine); writefln("Now will replace with new record:"); Sales newday=new Sales; newday.inputDay; newday.inputMonth; newday.inputYear; newday.inputSalesAmounts; output.seekSet(post); output.writeLine(newday.toString); writefln("Current position:%d",output.position); resp=askForChar("Do you want to edit another record? (Y/N)"); }while(resp=='y'||resp=='Y'); output.close; writefln("All Done."); } void testinput() { double input=askFor!(double); writefln("OK"); char ch=askForChar("Continue?(N/Y)"); writefln("OK"); writefln("%d","\b\n".length); } int main(string[] args) { mainMenu; pause; return 0; }
数据文件SALES.DAT样板:
07/13/2009 , 0.50 , 0.33 , 89.45 , 0.99 , 0.70
07/02/2009 , 2345.67 , 12345.67 , 90.50 , 100.00 , 890.00
07/09/2009 , 123.55 , 1234.77 , 1908.00 , 345.99 , 1123.45
07/04/2009 , 234.56 , 98.09 , 4567.89 , 20000.00 , 234.00
07/05/2009 , 345.05 , 34.50 , 1234.56 , 23456.78 , 34.90
07/12/2009 , 2345.67 , 8976.00 , 98.00 , 987.50 , 34.00