Tải bản đầy đủ - 0 (trang)
Chapter 4.  Strings and Text

Chapter 4.  Strings and Text

Tải bản đầy đủ - 0trang

andLinesinaTextFile

Recipe4.18.CountingInstancesofEachWordinaTextFile

Recipe4.19.AddMarginstoaTextFile

Recipe4.20.JustifyaTextFile

Recipe4.21.SqueezeWhitespacetoSingleSpacesina

TextFile

Recipe4.22.AutocorrectTextasaBufferChanges

Recipe4.23.ReadingaComma-SeparatedTextFile

Recipe4.24.UsingRegularExpressionstoSplitaString



Introduction

Thischaptercontainsrecipesforworkingwithstringsandtext

files.MostC++programs,regardlessoftheirapplication,

manipulatestringsandtextfilestosomedegree.Despitethe

varietyofapplications,however,therequirementsareoftenthe

sameforstrings:trimming,padding,searching,splitting,andso

on;fortextfiles:wrapping,reformatting,readingdelimited

files,andmore.Therecipesthatfollowprovidesolutionsto

manyofthesecommonneedsthatdonothaveready-made

solutionsintheC++standardlibrary.

Thestandardlibraryisportable,standardized,and,ingeneral,

atleastasefficientashomemadesolutions,sointhefollowing

examplesIhavepreferreditovercodefromscratch.Itcontains

arichframeworkformanipulatingandmanagingstringsand

text,muchofwhichisintheformoftheclasstemplates

basic_string(forstrings),basic_istream,andbasic_ostream(forinput

andoutputtextstreams).Almostallofthetechniquesinthis

chapteruseorextendtheseclasstemplates.Incaseswhere

theydidn'thavewhatIwanted,Iturnedtoanotherareaofthe

standardlibrarythatisfullofgeneric,prebuiltsolutions:

algorithmsandcontainers.

Everybodyusesstrings,sochancesarethatifwhatyouneed

isn'tinthestandardlibrary,someonehaswrittenit.TheBoost

StringAlgorithmslibrary,writtenbyPavolDroba,fillsmanyof

thegapsinthestandardlibrarybyimplementingmostofthe

algorithmsthatyou'vehadtouseatonetimeoranother,andit

doesitinaportable,efficientway.CheckouttheBoostproject

atwww.boost.orgformoreinformationanddocumentationof

theStringAlgorithmslibrary.Thereissomeoverlapbetween

theStringAlgorithmslibraryandthesolutionsIpresentinthis

chapter.Inmostcases,Iprovideexamplesoforatleast

mentionBoostalgorithmsthatarerelatedtothesolutions

presented.



Formostexamples,Ihaveprovidedbothanontemplateanda

templateversion.Ididthisfortworeasons.First,mostofthe

areasofthestandardlibrarythatusecharacterdataareclass

orfunctiontemplatesthatareparameterizedonthetypeof

character,narrow(char)orwide(wchar_t).Byfollowingthis

model,youwillhelpmaximizethecompatibilityofyour

softwarewiththestandardlibrary.Second,whetheryouare

workingwiththestandardlibraryornot,classandfunction

templatesprovideanexcellentfacilityforwritinggeneric

software.Ifyoudonotneedtemplates,however,youcanuse

thenontemplateversions,thoughIrecommendexperimenting

withtemplatesifyouarenewtothem.

Thestandardlibrarymakesheavyuseoftemplatesanduses

typedefstoinsulateprogrammersfromsomeoftheverbose

syntaxthattemplatesuse.Asaresult,Iusetheterms

basic_string,string,andwstringinterchangeably,sincewhat

appliestooneusuallyappliestothemall.stringandwstringare

justtypedefsforbasic_stringandbasic_string.

Finally,youwillprobablynoticethatnoneoftherecipesinthis

chapteruseC-stylestrings,i.e.,null-terminatedcharacter

arrays.Thestandardlibraryprovidessuchawealthofefficient

andextensiblesupportforC++stringsthattouseC-style

stringfunctions(whichwereprovidedprimarilyforbackwardcompatibilityanyway)istoforegotheflexibility,safety,and

genericnatureofwhatyougetforfreewithyourcompiler:C++

stringclasses.



Recipe4.1.PaddingaString

Problem

Youneedto"pad,"orfill,astringwithanumberofoccurrences

ofsomecharactertoacertainwidth.Forexample,youmay

wanttopadthestring"Chapter1"to20characterswidewith

periods,sothatitlookslike"Chapter1...........".



Solution

Usestring'sinsertandappendmemberfunctionstopadastring

withcharactersonthebeginningorend.Forexample,topad

theendofastringto20characterswithX's:

std::strings="foo";

s.append(20-s.length(),'X');



Topadthestringatthebeginninginstead:

s.insert(s.begin(),20-s.length(),'X');



Discussion

Thedifferenceinusagebetweenthetwofunctionsisinsert's

firstparameter.Itisaniteratorthatpointstothecharacter

immediatelytotherightofwheretheinsertshouldoccur.The



beginmemberfunctionreturnsaniteratorpointingtothefirst



elementinthestring,sointheexample,theseriesof

charactersisinsertedtotheleftofthat.Theparameters

commontobothfunctionsarethenumberoftimestorepeat

thecharacterandthecharacteritself.

insertandappendareactuallymemberfunctionsofthe

basic_stringclasstemplateintheheader(stringisa

typedefforbasic_stringandwstringisatypedeffor

basic_string),sotheyworkforstringsofnarroworwide



characters.Usingthemasneeded,asintheaboveexample,

willworkfine,butifyouareusingbasic_stringmemberfunctions

fromwithinyourowngenericutilityfunctions,youshouldbuild

onthestandardlibrary'sexistinggenericdesignandusea

functiontemplate.ConsiderthecodeinExample4-1,which

definesagenericpadfunctiontemplatethatoperateson

basic_strings.



Example4-1.Agenericpadfunctiontemplate

#include

#include

usingnamespacestd;

//Thegenericapproach

template

voidpad(basic_string&s,

typenamebasic_string::size_typen,Tc){

if(n>s.length())

s.append(n-s.length(),c);

}

intmain(){

strings="AppendixA";



wstringws=L"Acknowledgments";//The"L"indicatesthat

//thisisawidechar

pad(s,20,'*');//literal

pad(ws,20,L'*');

//cout<
wcout<
}



padinExample4-1padsthegivenstringsuptosomewidthn,



withthecharacterc.Sincethefunctiontemplateusesa

parameterizedtypefortheelementsofthestring(T),itwill

workonabasic_stringofanykindofcharacter:char,wchar_t,or

othercustomcharacters.



Recipe4.2.TrimmingaString

Problem

Youneedtotrimsomenumberofcharactersfromtheend(s)of

astring,usuallywhitespace.



Solution

Useiteratorstoidentifytheportionofthestringyouwantto

remove,andtheerasememberfunctiontoremoveit.Example

4-2presentsthefunctionrtrimthattrimsacharacterfromthe

endofastring.



Example4-2.Trimmingcharactersfromastring

#include

#include

//Theapproachfornarrowcharacterstrings

voidrtrim(std::string&s,charc){

if(s.empty())

return;

std::string::iteratorp;

for(p=s.end();p!=s.begin()&&*--p==c;);

if(*p!=c)

p++;



s.erase(p,s.end());

}

intmain()

{

std::strings="zoo";

rtrim(s,'o');

std::cout<
}



Discussion

Example4-2willdothetrickforstringsofchars,butitonly

worksforcharstrings.JustlikeyousawinExample4-1,youcan

takeadvantageofthegenericdesignofbasic_stringandusea

functiontemplateinstead.Example4-3usesafunction

templatetotrimcharactersfromtheendofanykindof

characterstring.



Example4-3.Agenericversionofrtrim

#include

#include

usingnamespacestd;

//Thegenericapproachfortrimmingsingle

//charactersfromastring

template

voidrtrim(basic_string&s,Tc)



{

if(s.empty())

return;

typenamebasic_string::iteratorp;

for(p=s.end();p!=s.begin()&&*--p==c;);

if(*p!=c)

p++;

s.erase(p,s.end());

}

intmain(){

strings="Great!!!!";

wstringws=L"Super!!!!";

rtrim(s,'!');

rtrim(ws,L'!');

cout<
wcout<
}



Thisfunctionworksexactlythesamewayastheprevious,

nongeneric,versioninExample4-2,butsinceitis

parameterizedonthetypeofcharacterbeingused,itwillwork

forbasic_stringsofanykind.

ExamplesExample4-2andExample4-3removesequencesofa

singlecharacterfromastring.Trimmingwhitespaceisdifferent,

however,becausewhitespacecanbeoneofseveralcharacters.

Conveniently,thestandardlibraryprovidesaconcisewaytodo

this:theisspacefunctionintheheader(anditswchar_t



equivalent,iswspace,in).Example4-4definesageneric

functionthattrimstrailingwhitespace.



Example4-4.Trimtrailingwhitespace

#include

#include

#include

#include

usingnamespacestd;

template

voidrtrimws(basic_string&s,Ff){

if(s.empty())

return;

typenamebasic_string::iteratorp;

for(p=s.end();p!=s.begin()&&f(*--p););

if(!f(*p))

p++;

s.erase(p,s.end());

}

//Overloadstomakecleanercallingforclientcode

voidrtrimws(string&s){

rtrimws(s,isspace);

}

voidrtrimws(wstring&ws){

rtrimws(ws,iswspace);

}



intmain(){

strings="zing";

wstringws=L"zong";

rtrimws(s);

rtrimws(ws);

cout<
wcout<
}



ThefunctiontemplateinExample4-4,rtrimws,isageneric

functiontemplate,similartothepreviousexamples,that

acceptsabasic_stringandtrimswhitespacefromtheendofit.

Butunliketheotherexamples,ittakesafunctionobject,and

notacharacter,thatisusedtotestanelementofthestringto

determinewhetheritshouldberemoved.

Youdon'tneedtooverloadrtrimwsasIdidintheexample,butit

makesthesyntaxcleanerwhenusingthefunction,sincethe

callingcodecanomitthepredicatefunctionargumentwhen

usingthem.

Butalas,thissolutionrequiresthatyouwritethecodeyourself.

IfyouwouldratherusealibraryandagoodoneatthatBoost's

StringAlgorithmslibrarysupplieslotsoffunctionsfortrimming

strings,andchancesarethatwhatyouneedisalreadythere.In

fact,therearelotsofhandytrimmingfunctionsintheString

Algorithmslibrary,soifyoucanuseBoostyoushouldtakea

look.Table4-1liststhefunctiontemplatesinthelibrarythat

youcanusefortrimmingstrings,includingsomemiscellaneous

functions.Sincethesearefunctiontemplates,theyhave

templateparametersthatrepresentthedifferenttypesused.

Hereiswhateachofthemmean:



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 4.  Strings and Text

Tải bản đầy đủ ngay(0 tr)

×