Ch2A more elaborate example.docx
- 文档编号:26806947
- 上传时间:2023-06-22
- 格式:DOCX
- 页数:10
- 大小:19.23KB
Ch2A more elaborate example.docx
《Ch2A more elaborate example.docx》由会员分享,可在线阅读,更多相关《Ch2A more elaborate example.docx(10页珍藏版)》请在冰豆网上搜索。
Ch2Amoreelaborateexample
Chapter2,Amoreelaborateexample
ToillustrateseveralofthefundamentalpointsofPikewewillnowintroduceanexampleprogram,thatwillbeextendedaswego.Wewillbuildadatabaseprogramthatkeepstrackofarecordcollectionandthesongsontherecords.Inthefirstversionwehard-codeour"database"intotheprogram.Thedatabaseisamappingwheretheindexistherecordnameandthedataisanarrayofstrings.Thestringsareofcoursethesongnames.Thedefaultregisterconsistsofonerecord.
#!
/usr/local/bin/pike
mapping(string:
array(string))records=
([
"StarWarsTrilogy":
({
"FoxFanfare",
"MainTitle",
"PrincessLeia'sTheme",
"HereTheyCome",
"TheAsteroidField",
"Yoda'sTheme",
"TheImperialMarch",
"ParadeoftheEwoks",
"LukeandLeia",
"FightwithTieFighters",
"JabbatheHut",
"DarthVader'sDeath",
"TheForestBattle",
"Finale"
})
]);
Wewanttobeabletogetasimplelistoftherecordsinourdatabase.Thefunctionlist_recordsjustgoesthroughthemappingrecordsandputstheindices,i.e.therecordnames,inanarrayofstrings,record_names.Byusingthebuiltinfunctionsortweputtherecordnamesintothearrayinalphabeticalorderwhichmightbeanicetouch.Fortheprintoutwejustprintaheader,"Records:
",followedbyanewline.Thenweusetheloopcontrolstructurefortotraversethearrayandprinteveryiteminit,includingthenumberoftherecord,bycountingupfromzerotothelastitemofthearray.Thebuiltinfunctionsizeofgivesthenumberofitemsinanarray.TheprintoutisformattedthroughtheuseofsprintfwhichworksmoreorlessliketheCfunctionofthesamename.
voidlist_records()
{
inti;
array(string)record_names=sort(indices(records));
write("Records:
\n");
for(i=0;i write(sprintf("%3d: %s\n",i+1,record_names[i])); } Ifthecommandlinecontainedanumberourprogramwillfindtherecordofthatnumberandprintitsnamealongwiththesongsofthisrecord.Firstwecreatethesamearrayofrecordnamesasinthepreviousfunction,thenwefindthenameoftherecordwhosenumber(num)wegaveasanargumenttothisfunction.Nextweputthesongsofthisrecordinthearraysongsandprinttherecordnamefollowedbythesongs,eachsongonaseparateline. voidshow_record(intnum) { inti; array(string)record_names=sort(indices(records)); stringname=record_names[num-1]; array(string)songs=records[name]; write(sprintf("Record%d,%s\n",num,name)); for(i=0;i write(sprintf("%3d: %s\n",i+1,songs[i])); } Themainfunctiondoesn'tdomuch;itcheckswhethertherewasanythingonthecommandlineaftertheinvocation.Ifthisisnotthecaseitcallsthelist_recordsfunction,otherwiseitsendsthegivenargumenttotheshow_recordfunction.Whenthecalledfunctionisdonetheprogramjustquits. intmain(intargc,array(string)argv) { if(argc<=1) { list_records(); }else{ show_record((int)argv[1]); } } 2.1Takingcareofinput Now,itwouldbebetterandmoregeneralifwecouldentermorerecordsintoourdatabase.Let'saddsuchafunctionandmodifythemain()functiontoaccept"commands". 2.1.1add_record() UsingthemethodStdio.Readline()->read()wewaitforinputwhichwillbeputintothevariablerecord_name.Theargumentto->read()isprintedasapromptinfrontoftheuser'sinput.Readlinetakeseverythinguptoanewlinecharacter.Nowweusethecontrolstructurewhiletocheckwhetherweshouldcontinueinputtingsongs.Thewhile (1)means"loopforever",because1isalwaystrue.Thisprogramdoesnotinfactloopforever,becauseitusesreturntoexitthefunctionfromwithintheloopwhenyoutypeaperiod.Whensomethinghasbeenreadintothevariablesongitischecked.Ifitisa"."wereturnanullvaluethatwillbeusedinthewhilestatementtoindicatethatitisnotoktocontinueaskingforsongnames.Ifitisnotadot,thestringwillbeaddedtothearrayofsongsforthisrecord,unlessit'sanemptystring.Notethe+=operator.Itisthesameassayingrecords[record_name]=records[record_name]+({song}). voidadd_record() { stringrecord_name=Stdio.Readline()->read("Recordname: "); records[record_name]=({}); write("Inputsongnames,oneperline.Endwith'.'onitsownline.\n"); while (1) { stringsong; song=Stdio.Readline()->read(sprintf("Song%2d: ", sizeof(records[record_name])+1)); if(song==".") return; if(strlen(song)) records[record_name]+=({song}); } } 2.1.2main() Themainfunctionnowdoesnotcareaboutanycommandlinearguments.InsteadweuseStdio.Readline()->read()toprompttheuserforinstructionsandarguments.Theavailableinstructionsare"add","list"and"quit".Whatyouenterintothevariablescmdandargsischeckedintheswitch()block.Ifyouentersomethingthatisnotcoveredinanyofthecasestatementstheprogramjustsilentlyignoresitandasksforanewcommand.Inaswitch()theargument(inthiscasecmd)ischeckedinthecasestatements.Thefirstcasewheretheexpressionequalscmdthenexecutesthestatementafterthecolon.Ifnoexpressionisequal,wejustfallthroughwithoutanyaction.Theonlycommandthattakesanargumentis"list"whichworksasinthefirstversionoftheprogram.If"list"receivesanargument,thatrecordisshownalongwithallthesongsonit.Ifthereisnoargumentitshowsalistoftherecordsinthedatabase.Whentheprogramreturnsfromeitherofthelistingfunctions,thebreakinstructiontellstheprogramtojumpoutoftheswitch()block."add"ofcourseturnscontrolovertothefunctiondescribedabove.Ifthecommandgivenis"quit"theexit(0)statementstopstheexecutionoftheprogramandreturns0(zero)totheoperatingsystem,tellingitthateverythingwasok. intmain(intargc,array(string)argv) { stringcmd; while(cmd=Stdio.Readline()->read("Command: ")) { stringargs; sscanf(cmd,"%s%s",cmd,args); switch(cmd) { case"list": if((int)args) { show_record((int)args); }else{ list_records(); } break; case"quit": exit(0); case"add": add_record(); break; } } } 2.2Communicatingwithfiles Nowifwewanttosavethedatabaseandalsobeabletoretrievepreviouslystoreddatawehavetocommunicatewiththeenvironment,i.e.withfilesondisk.Nowwewillintroduceyoutoprogrammingwithobjects.ToopenafileforreadingorwritingwewilluseoneoftheprogramswhichisbuiltininPikecalledStdio.File.ToPike,aprogramisadatatypewhichcontainscode,functionsandvariables.AprogramcanbeclonedwhichmeansthatPikecreatesadataareainmemoryfortheprogram,placesareferencetotheprograminthedataarea,andinitializesittoactonthedatainquestion.Themethods(i.e.functionsintheobject)andvariablesintheobjectStdio.Fileenableustoperformactionsontheassociateddatafile.Themethodsweneedtouseareopen,read,writeandclose.Seechapter9"FileI/O"formoredetails. 2.2.1save() FirstwecloneaStdio.Fileprogramtotheobjecto.Thenweuseittoopenthefilewhosenameisgiveninthestringfile_nameforwriting.Weusethefactthatifthereisanerrorduringopening,open()willreturnafalsevaluewhichwecandetectandactuponbyexiting.Thearrowoperator(->)iswhatyouusetoaccessmethodsandvariablesinanobject.Ifthereisnoerrorweuseyetanothercontrolstructure,foreach,togothroughthemappingrecordsonerecordatatime.Weprecederecordnameswiththestring"Record: "andsongnameswith"Song: ".Wealsoputeveryentry,beitsongorrecord,onitsownlinebyaddinganewlinetoeverythingwewritetothefile. Finally,remembertoclosethefile. voidsave(stringfile_name) { stringname,song; Stdio.Fileo=Stdio.File(); if(! o->open(file_name,"wct")) { write("Failedtoopenfile.\n"); return; } foreach(indices(records),name) { o->write("Record: "+name+"\n"); foreach(records[name],song) o->write("Song: "+song+"\n"); } o->close(); } 2.2.2load() Theloadfunctionbeginsmuchthesame,exceptweopenthefilenamedfileforreadinginstead.Whenreceivingdatafromthefileweputitinthestringfile_contents.Theabsenceofargumentstothemethodo->readmeansthatthereadingshouldnotenduntiltheendofthefile.Afterhavingclosedthefileweinitializeourdatabase,i.e.themappingrecords.Thenwehavetoputfile_contentsintothemappingandwedothisbysplittingthestringonnewlines(cf.thesplitoperatorinPerl)usingthedivisionoperator.Yes,that'sright: bydividingonestringwithanotherwecanobtainanarrayconsistingofpartsfromthefirst.Andbyusingaforeachstatementwecantakethestringfile_contentsapartpiecebypiece,puttingeachpiecebackinitsproperplaceinthemappingrecords. voidload(stringfile_name) { stringname="ERROR"; stringfile_contents,line; Stdio.Fileo=Stdio.File(); if(! o->open(file_name,"r")) { write("Failedtoopenfile.\n"); return; } file_contents=o->read(); o->close(); record
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Ch2A more elaborate example