; TeX output 1995.11.30:1652y?DtGGcmr17Counqting7twordsXQ cmr12SilvioLevyؿDonaldE.KnruthfjAugust29,1995&->Nff cmbx121VLAnffexampleof߆Tff cmtt12CWEB>K`y cmr10This8example,qbasedonaprogrambyKlausGuntermannandJoachimSchroGd[1] >presents&the\wordcount"programfromo cmr9UNIX,rewritteninstrate:literateprogramminginC.^ٓRcmr71 ThelevelofdetailinthisdoGcumentis>intentionally"{high,UfordidacticpurpGoses;manyofthethingsspelledouthere>don'tUUneedtobGeexplainedinotherprograms.MThepurpGoseofwcistocountlines,words,and/orcharactersinalistof les.>The>numbGeroflinesina leisthenumbGerofnewlinecharactersitcontains.>ThenumbGerofcharactersisthe lelengthinbytes.tA^\word"isamaximal>sequenceTofconsecutivecharactersotherthannewline,Uspace,orTtab,containing>at?leastonevisibleASCIGI)code.m(W*e?assumethatthestandardASCIGIcode?is>inUUuse.)>9 !", cmsy10{NsMostCWEBprogramsshareacommonstructure.T;It'sprobablyagoGodidea>tostatetheoverallstructureexplicitlyattheoutset,?eventhoughthevqarious>partsscouldallbGeintroducedinunnamedsectionsofthecodeifwewantedto>addUUthempiecemeal.MHere,then,is8anoverview8ofthe lewcltx.cthatisde nedbythisCWEB>programUUwcltx.w:*XHhHeaderUU lestoinclude@|{Ycmr83i.`92 HhGlobalUUvqariables@4iHhF*unctions@20iHhTheUUmainprogram@5i>9{NsW*e!mustincludethestandardI/Ode nitions,4sincewewanttosendfor->mattedUUoutputto': cmti10stdout"rβandstderry.*X>hHeaderUU lestoinclude@3i.`93 >#"V cmbx10include'~ X>ThisXcoffv D| 0ncmsy5LܹL#Aacmr6A TAuEMXmarkupXbÎyJoachimSchro "5-:1LܹIncidenÎtallyJ,cNKlausFGuntermannandJoachimSchro9{NsThe$status!vqariable$willtelltheopGeratingsystemiftherunwassuccessful >orUUnot,andpr}'ogffname5"isusedincasethere'sanerrormessagetobGeprinted.>#de nei'OK}޲0 b> cmmi10=status"coGdeUUforsuccessfulrun=.`94 >#de nei'usagefferr}'or꽲1꿵=status"coGdeUUforimpropersyntax=>#de nei'c}'annotffopenff le>}2>=status"coGdeUUfor leaccesserror=>hGlobalUUvqariables@4iHin9tYstatusw Ͳ=OK z;=exitUUstatusofcommand,initiallyOK[=Hc9harajJfjKpr}'ogffname✲;=whoUUweare= >SeeXalsocÎhunkX14.>ThisXco9{NsNowUUwecometothegenerallayoutofthemain/function.>hTheUUmainprogram@5i.`95 Hmain_A(ar}'gcʵ;ar}'gvEI) \in9tmar}'gcIJ;k=theUUnumbGerofargumentsontheUNIXcommandline=\c9harujLzjMjNar}'gv;=theUUargumentsthemselves,anarrayofstrings=HfRhV*ariablesUUloGcaltomain޹6iRpr}'ogffname?k=ar}'gva[0];RhSetUUupoptionselection@7i;RhProGcessUUallthe les@8i;RhPrintUUthegrandtotalsifthereweremultiple les@19i;Rexitcc(status);Hg >ThisXco9{NsIfthe rstargumentbGeginswitha`-',theuserischoGosingthedesiredcounts>andspGecifyingtheorderinwhichtheyshouldbedisplayed. Eachselectionis>given,bytheinitialcharacter(lines,bwords,or,characters).MF*orexample,b`-cl'>wouldcausejustthenumbGerofcharactersandthenumbGeroflinestobeprinted,>inUUthatorder.MW*etdonotproGcessthisstringnow;wetsimplyrememberwhereitis.$Itwill>bGeUUusedtocontroltheformattingatoutputtime.>hV*ariablesUUloGcaltomain޹6i.`96 Hin9tY leffc}'ount;=howUUmany lesthereare=Hc9harajJfjKwhich:;=whichUUcountstoprint= >SeeXalsocÎhunksX9and12.>ThisXco9{NshSetUUupoptionselection@7i.`97 Hwhichdղ="lwc"q;=ifUUnooptionisgiven,printallthreevqalues= HifS(ar}'gc>1 ^88ar}'gvӂ[1]'-' w)fRwhichnֲ=ar}'gva[1]8+18;Rar}'gceΟ O!cmsy7j˟qβ;Rar}'gvf+k>1+qò;HgH leffc}'ountt4²=ar}'gc¸818; >ThisXco9{NsNow&wescantheremainingargumentsandtrytoopGena le,ZHifpossible.>The leisproGcessedanditsstatisticsaregiven.W*euseado6...jwhile$_loop>bGecauseUUweshouldreadfromthestandardinputifno lenameisgiven.>hProGcessUUallthe les@8i.`98 Har}'gc[͟`ʟgͲ;HdoYfRhIfUUa leisgiven,trytoopGenUV(++ G ar}'gv);qcon9tinue2Ѳifunsuccessful@10i;RhInitializeUUpGointersandcounters@13i;RhScanUU le@15i;RhW*riteUUstatisticsfor le@17i;RhCloseUU le@11i;RhUpGdateUUgrandtotals@18i;=evenifthereisonlyone le=Hg while(C,( ar}'gc"^>0); >ThisXco9{NsHere'sUthecoGdetoopenthe le.A6specialtrickallowsustohandleinput>fromdstdinFwhendnonameisgiven.Recallthatthe ledescriptortostdinis0;>that'sUUwhatweuseasthedefaultinitialvqalue.>hV*ariablesUUloGcaltomain޹6i+.`99 Hin9tYfdf$=0;= leUUdescriptor,initializedtostdinҒ=$>9{Ns#de neyϚREAD_ONLY0ʥ =ɲread!accesscoGdeforsystemop}'enTeroutine=)910 >hIfUUa leisgiven,trytoopGenUV(++ G ar}'gv);qcon9tinue2Ѳifunsuccessful@10iHifS( leffc}'ount,4>0 ^8(fd =op}'en;((++ G ar}'gv);READ_ONLY1p))<0)fRfprintfpH(stderr$;"%s: cannot open filk0e %s\n"w';pr}'ogffname0";ar}'gvEJ);Rstatusoh׸jr/=|*c}'annotffopenff le+;R leffc}'ount{-;Rcon9tinue|淲;Hg>ThisXco9{NshCloseUU le@11i)911 Hclose^7̲(fd ); ww>ThisXco9{NsW*eUwilldosomehomemadebu eringinordertospGeedthingsup:Characters >will60bGereadintothebu er earraybGeforeweproGcessthem.geT*odothiswesetup>appropriateUUpGointersandcounters.w>#de nei'bufffsizeoBUFSIZƵ=stdio.h's5VBUFSIZ&qis5Vchosenforeciency=)912 ww>hV*ariablesUUloGcaltomain޹6i+Hc9harajJbu er{O[bufffsize!];=weUUreadtheinputintothisarray=Hregisterqc9harJ@JAptr;=theUU rstunproGcessedcharacterinbu er"W=Hregisterqc9harJ@JAbufffendቲ;=theUU rstunusedpGositioninbu er"W=Hregisterqin9tcɲ;W=currentUUcharacter,ornumbGerofcharactersjustread=Hin9tYinffwor}'d|!:;=areUUwewithinaword?o=Hlonga&wor}'dffcount_õ;lineffc}'ount1~;charffc}'ount4{;W=numbGerUUofwords,lines,andcharactersfoundinthe lesofar=#͍>9{NshInitializeUUpGointersandcounters@13i)913 HptrY=bufffend'%x=bu erH;Hlineffc}'ountwEҲ=wor}'dffcount66=charffc}'ount5>=0;Hinffwor}'dmC[=0; ww>ThisXco9{NsThegrandtotalsmustbGeinitializedtozeroatthebeginningoftheprogram.>IfwemadethesevqariablesloGcaltomain#N,wewouldhavetodothisinitialization>explicitly;Dhowever, C'sglobalsareautomaticallyzeroGed.??(Orrather,\statically>zeroGed.")q(GetUUit?)w>hGlobalUUvqariables@4i+)914 Hlonga&totffwor}'dffcount<;totfflineffc}'ount@/;totffcharffc}'ountD;W=totalUUnumbGerofwords,lines,andchars=#͍>9{NsTheBpresentsection,FwhichdoGesthecountingthatiswc'sr}'aisond'^$etre,Fwas>actually0oneofthesimplesttowrite.=W*eloGokateachcharacterandchange>stateUUifitbGeginsorendsaword.w>hScanUU le@15i)915 HwhilefC-(1)fRhFillUUbu er!+ifUUitisempty;qbreak$hatendof le@16i;RcY=ptr+n+"K;Rif](c>' 'FW^8c S<^_177F)f=visibleUUASCIGIcodes=\ifg(:inffwor}'d"|B)f4$y?fwor}'dffcount +ܘ+*; finffwor}'dC^=1;\g\con9tinue渲;RgRif](c'\n'Mt)lineffc}'ount1+7"G+=ٲ;Relseh.6ifs.(c6=' 'FW^8c SӸ6='\t'Mt)con9tinue/浲;Rinffwor}'dwC\=0;=c -isUUnewline,space,ortab=Hg >ThisXco9{NsBu eredUUI/OallowsustocountthenumbGerofcharactersalmostforfree.>hFillUUbu er!+ifUUitisempty;qbreak$hatendof le@16i)916 HifS(ptr߸bufffend$^`)fRptrc=bu erH;RcY=r}'eadV(fd ;ptro;bufffsize#|);Rif](c0)break!d;Rcharffc}'ountw+=c Dz;Rbufffendv^b=bu er+8c;Hg>ThisXco9{NsIt'sconvenienttooutputthestatisticsbyde ninganewfunctionwcffprint(²;>then=thesamefunctioncanbGeusedforthetotals.^Additionallywemustdecide>hereUUifweknowthenameofthe lewehaveproGcessedorifitwasjuststdinҕ.>hW*riteUUstatisticsfor le@17i)917 Hwcffprintm (whichϼ;charffc}'ount1[&;wor}'dffcount2㮵;lineffc}'ount.)a);HifS( leffc}'ount)m)printf 6(" %s\n"%FS;ar}'gvEJ);=notUUstdinҒ=Helse_printfz("\n"\);=stdin }:=>ThisXco9{NshUpGdateUUgrandtotals@18i)918 Htotfflineffc}'ountK+= lineffc}'ountʼnX;Htotffwor}'dffcounto+=wor}'dffcount;Htotffcharffc}'ount+=ThisXco9{NsW*emightaswellimproveabitonUNIX'swcbydisplayingthenumbGerof> lesUUtoGo.52Ǡy?>hPrintUUthegrandtotalsifthereweremultiple les@19i)919 HifS( leffc}'ount,4>1)f Rwcffprintw(whichϼ;totffcharffc}'ount@ʟ;totffwor}'dffcountBS';totfflineffc}'ount=ڲ);Rprintfm 8(" total in %d files\i,n"t; leffc}'ount+Q);Hg >ThisXco9{NsHereInowisthefunctionthatprintsthevqaluesaccordingtothespGeci ed>options.&eThes/callingroutineissuppGosedtosupplyanewline.Ifaninvqalidoption>characterisfoundweinformtheuserabGoutproperusageofthecommand.>CountsUUareprintedin8-digit eldssothattheywilllineupincolumns.>#de nei'printffc}'ountq(n)UUprintf#^("%8ld" V;nB))920 >hF*unctions@20iHwcffprintm (whichϼ;charffc}'ount1[&;wor}'dffcount2㮵;lineffc}'ount.)a)\c9harujLzjMwhich: ;=whichUUcountstoprint=\longu&charffc}'ount=;wor}'dffcount69;lineffc}'ount1~;=givenUUtotals=HfRwhilepC.(whichϽ)\switc9hܲ(whichO+$sK++ݲ)f\casetj'l':printffc}'ount6J(lineffc}'ount,~);fbreakh;\casetj'w':printffc}'ount6J(wor}'dffcount19);fbreakh;\casetj'c':printffc}'ount6J(charffc}'ount/~);fbreakh;\defaultd:fifq((statusڝ&8usagefferr}'or5!)0)fpfprintfK(stderr$;"\nUsage: %s [-lwc] k0[filename ...]\n" ;pr}'ogffnamexX);pstatushڸj/=-usagefferr}'or͠n;fg\gHg>ThisXco9{NsIncidentally*,aa,testofthisprogramagainstthesystemwccommandona>SP*ARCstationshowedthatthe\ocial"wcwasslightlyslower.-F*urthermore,>althoughbthatwcgavebanappropriateerrormessagefortheoptions`-abc',%it>madewnocomplaintsabGouttheoptions`-labc'r!'Darewesuggestthatthesystem>routinemighthavebGeenbetterifitsprogrammerhadusedamoreliterate>approach?6>Hy?>References>[1]M;KlausGuntermannandJoachimSchroGd. WEB;adaptedtoC.TUGb}'oat, M;7(3):134{137,UU1986.7K y?፟'>Index>Here.isalistoftheidenti ersused,6aandwheretheyappGear.dUnderlinedentries >indicateUUtheplaceofde nition.qErrormessagesarealsoshown.'ፍ>ar}'gcQʲ: 5 fe,7,8. >ar}'gvQ: 5 fe,D7,10,17.>bufffend_H: 12 fe ,k13,16.>bufffsize_: 12 fe ,y16.>bu erX: 12 fe ,13,16.>BUFSIZ^V: 12.>cBS۲: 12 fe .>cannot?openfile8: 10.>c}'annotffopenff le6: 4 fe,+10.>charffc}'ountm~: 12 fe ,ZP13,16,17,18,20fe  ZR.>closeT7˲: 11.>exitOa: 5.>fdG: 9 fe,810,11,16.> leffc}'ountgm: 6 fe,7,10,17,19.>fprintf\F: 10,20.>inffwor}'d`|B: 12 fe ,g613,15.>Joke: 14.>lineffc}'ountj~: 12 fe ,g13,15,17,18,20fe  g.>mainUA: 5 fe,14.>OKIb: 4 fe.>op}'enS6#: 10.>printffc}'ountoJ: 20 fe .>printfY 6: 17,19,20.>pr}'ogffnamelxQ: 4 fe,5,10,20.>ptrL<Dz: 12 fe ,t`13,15,16.>r}'eadQ: 16.>READ_ONLYmM: 10 fe .>statusX: 4 fe,j5,10,20.>stderrY$: 3,10,20.>stdinT}@: 9,17.>stdoutY$: 3.>totffcharffc}'ount}: 14 fe ,/18,19.>totfflineffc}'ounty2: 14 fe ,!18,19.>totffwor}'dffcount~: 14 fe ,~18,19.>Usage: ...xFG: 20.>usagefferr}'orpA: 4 fe,20.>wcffprintc : 17,Y19,20fe Y.>whichWϼ: 6 fe,$7,17,19,20fe $.>wor}'dffcounto9: 12 fe ,D:13,15,17,18,20fe  D<.8 Ky?>ListffofRe nements>hCloseUU le@11i UsedXincÎhunkX8. >hFillUUbu er!+ifUUitisempty;break#Latendof le@16i UsedXincÎhunkX15.>hF*unctions@20i UsedXincÎhunkX2.>hGlobalUUvqariables@4,X14i UsedincÎhunk2.>hHeaderUU lestoinclude@3i UsedXincÎhunkX2.>hIf{a leisgiven,trytoopGen|(++ G ar}'gv);con9tinue2@ifunsuccessful@10i UsedRinXcÎhunk8.>hInitializeUUpGointersandcounters@13i UsedXincÎhunkX8.>hPrintUUthegrandtotalsifthereweremultiple les@19i UsedXincÎhunkX5.>hProGcessUUallthe les@8i UsedXincÎhunkX5.>hScanUU le@15i UsedXincÎhunkX8.>hSetUUupoptionselection@7i UsedXincÎhunkX5.>hTheUUmainprogram@5i UsedXincÎhunkX2.>hUpGdateUUgrandtotals@18i UsedXincÎhunkX8.>hV*ariablesUUloGcaltomain޹6,X9,12i UsedincÎhunkX5.>hW*riteUUstatisticsfor le@17i UsedXincÎhunkX8.9Wy;y "V cmbx10': cmti10Cscmtt8 cmmi10K`y cmr10ٓRcmr7]c