turbo pascal strings

15
TURBO PASCAL STRINGS Strings are not a supported data type of standard Pascal, and so we must reply on the implementation of string handling afforded with various versions of Pascal. In this course, we use the string definitions and manipulation in Borland Turbo Pascal V7.0. Strings are arrays of characters of a specified maximum length. Strings are structured types; that is, they can be broken down into their individual components. Strings in Turbo Pascal V7 have a default length of 255 and are declared by the keyword String; otherwise, their maximum length must be declared when they are defined. Strings may grow dynamically from length 0 (= "empty string" or "null string") to an absolute maximum of length 255. Examples: Type File_name = String[14]; { max length = 14 } Employee_name = String[30]; Var Infile_name: File_name; Emp_name: Employee_name; Line: String; { max length = 255 } The READ and WRITE procedures support strings, so that (using the above definitions), Read(Emp_name) and Writeln(Infile_name) are legal Pascal statements. There are many methods for modifying and comparing strings: 1. STRING ASSIGNMENT SYMBOL: :=

Upload: marcio-greg-maia-carvalho

Post on 11-Nov-2014

144 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Turbo Pascal Strings

TURBO PASCAL STRINGSStrings are not a supported data type of standard Pascal, and so we must reply on the implementation of string handling afforded with various versions of Pascal. In this course, we use the string definitions and manipulation in Borland Turbo Pascal V7.0.

Strings are arrays of characters of a specified maximum length. Strings are structured types; that is, they can be broken down into their individual components. Strings in Turbo Pascal V7 have a default length of 255 and are declared by the keyword String; otherwise, their maximum length must be declared when they are defined. Strings may grow dynamically from length 0 (= "empty string" or "null string") to an absolute maximum of length 255. Examples:

Type File_name = String[14]; { max length = 14 } Employee_name = String[30];

Var Infile_name: File_name; Emp_name: Employee_name; Line: String; { max length = 255 }

The READ and WRITE procedures support strings, so that (using the above definitions), Read(Emp_name) and Writeln(Infile_name) are legal Pascal statements.

There are many methods for modifying and comparing strings:

1. STRING ASSIGNMENTSYMBOL: :=

Strings may be assigned values using the := operator.Example: Infile_name := 'A:\PROG006.OUT'; Note that if we attempted to make the following assignment: Infile_name :='A:\OUTPUT\PROG006.OUT', the value assigned to Infile_namewould be 'A:\OUTPUT\PROG' which may not be what we expected! Also, Infile_name[2] = ':' and Infile_name[11] = 'P'.

2. STRING CONCATENATION ("GLUE")SYMBOL: +

Example: Infile_name := 'A:\' + 'PROG006' + '.OUT';

3. INDIVIDUAL STRING ELEMENTS SYMBOL: St[n]

Page 2: Turbo Pascal Strings

Example: Writeln(Infile_name[3]);causes the third character of Infile_name to be printed.

4. STRING COMPARISONSYMBOLS: =, <, <=, >, >=, <>

If X and Y are strings, then X r Y is either TRUE or FALSE where r is any of the six relational characters listed above. X = Y is true if and only if their lengths are equal and X[i] = Y[i] for all i = 1, 2, .... When X and Y are compared, X[i] and Y[i] are compared in sequence according to their ASCII ordinal values. If the strings are of different length but equal character by character up to and including the last character of the shorter string, then the shorter string is considered smaller. Examples:

'A' < 'B' TRUE 'Z' < 'a' TRUE 'a' < 'B' FALSE 'TURBO' ='TURBO' TRUE 'TURBO' = 'Turbo' FALSE 'turbo ' = 'turbo' FALSE 'turbo ' > 'turbo' TRUE

STRING FUNCTIONS

5. LENGTHSyntax: Length(St)

Returns the current length of the string St in range 0..255.

Example:

Var St: String[20]; Len: Integer;

St := ''; { make St the null string } Len := Length(St); { Len now has value 0 } St := St + 'Begin'; Len := Length(St); { Len now has value 5 }

6. POSITIONSyntax: Pos(Pattern, Target)

The Pos function scans the string Target to find the first occurrence of the string Pattern in the string Target. The value returned by Pos is an integer indicating this position. When the string Patternis not found in Target, Pos returns the value zero.

Example:

Page 3: Turbo Pascal Strings

Var Target, Pattern: String[20]; Location: Integer;

Target := 'MISSISSIPPI'; Pattern := 'IS';

Location := Pos(Pattern, Target); { Location = 2 }

If Pattern = 'SIP', then Location = 7.If Pattern = 'is', then Location = 0.If Pattern = ' ', then Location = 0.

7. COPYSyntax: Copy(St, Start, Number)

The Copy function returns a substring copied out of St starting at position Start containing Number characters. Thus St is a string expression and Start and Number are positive integers. If Start > Length(St), the empty string is returned. If Start + Number > Length(St), only characters in the string St are returned. If Start is outside the range 1..255, a run-time error occurs.

Example:

Var St, Part: String[20]; Start, Number: Integer;

St := 'MISSISSIPPI'; Start := 5; Number := 3; Part := Copy(St, Start, Number); { Part = 'ISS' }

If Start = 12, then Part = ''.If Start = 5 and Number = 20, then Part = 'ISSIPPI'.

STRING PROCEDURES

8. DELETESyntax: Delete(St, Start, Number)

This procedure will alter St by removing Number characters from St beginning at position Start. If Start > Length(St), no characters will be removed from St. If Start + Number > Length(St), only characters in the string will be removed.

Example (using above defined storage):

St := 'MISSISSIPPI'; Start := 5; Number := 4;

Page 4: Turbo Pascal Strings

Delete(St, Start, Number); { St = 'MISSPPI' }

If Start = 15, St does not change.If Start = 2 and Number = 20, then Delete(St, Start, Number) changes St to 'M'.

9. INSERTSyntax: Insert(Pattern, Target, Position)

Insert actually places a copy of the string Pattern into the string Target to the left of the character at location Position. Thus Target will be altered by Insert. If Position > Length(Target), Pattern will be concatenated to the end of Target to the extent possible.

Example (using above defined storage):

Target := 'MISSISSIPPI'; Part := 'xyz'; Insert(Part, Target, 5); { Target = 'MISSxyzISSIPPI' }

If Part = 'abcdefghijkl' and Position = 7, then Insert(Part, Target, Position) changes Target to 'MISSISabcdefghijklSI'. If Position = 70, then Target = 'MISSISSIPPIabcdefghi'.

10.VALSyntax: VAL(St, Num, Error_code)

Purpose: to convert a string value which is in the form of a valid numeric quantity to the numeric value it represents. If the conversion can be made without error, the value is placed in Num (and the conversion is controlled by the declared numeric type of Num) and Error_code = 0. If an error occurs, the value of Num is unchanged; Error_code > 0 and points to the first position in St where a conversion error occurred. Examples:

Var Num_str: String[20]; R_Num: Real; I_num, Error: Integer;

Num_str := '23.45'; Val(Num_str, R_Num, Error); {R_Num = 23.45, Error = 0} Val(Num_str, I_Num, Error); {Error = 3; R_Num stays 23.45 } Num_str := '256,78'; Val(Num_str, R_Num, Error); {R_Num = 23.45, Error = 4} Num_str := '23456'; Val(Num_str, I_Num, Error); {I_Num = 23456, Error = 0} Val(Num_str, R_Num, Error); {R_Num = 23456.0, Error = 0}

Page 5: Turbo Pascal Strings

11.STRSyntax: STR(Numeric, St)

Purpose: to perform the inverse function of VAL; that is, to receive a numeric value and convert it (according to any formatting information) to a string.

Examples (using the storage defined in 10);Result is String[20]:

I_Num := -345; Str(I_num, Result); {Result = '-345'} R_num := 2345.678; Str(R_num :0:6, Result); {Result = '2345.678000'} Str(R_num :0:1, Result); {Result = '2345.7'} Str(R_num :10:2, Result); {Result = ' 2345.68'} Str(R_num, Result); {Result = ' 2.3456780000E+03'}

EXAMPLES OF THE USE OF THESE FUNCTIONS AND PROCEDURES:

Const Space = ' ';

Var St, First, Last: String[80]; Position, Len: Integer; Remove: Char;

1. Remove all lead blanks from a string2.3. St := ' now is the time';4. While POS(Space, St) = 1 Do5. Delete(St, 1, 1);

6. Reverse the order of names in 'Smith John'7.8. St := 'Smith John';9. Location := POS(Space, St); { Location = 6 }10. Len := Length(St); { Len = 10 }11. Last := COPY(St, 1, Location - 1); { Last = 'SMITH'}12. First := COPY(St, Location + 1, Len - Location);13. St := First + Space + Last;

14.Remove all specified characters from a string15.16. St := 'Txxhixs xsenxtxxencxe hxxaxs toxxox xmaxxny exxexes.';17. Remove := 'x';18. New := '';19. For Location := 1 to Length(St) Do20. If St[Location] <> Remove21. Then New := New + St[Location];

What's wrong with using a loop like this:

Page 6: Turbo Pascal Strings

For Location := 1 to Length(St) Do If St[Location] = Remove Then Delete(St, Location, 1);

Answer: will only remove isolated single 'x's in string

22.Insert a blank every fifth character in a string23.24. Const25. Blank = ' ';26.27. Var28. St, New: String[80];29. Location, Mid: 1..80;30.31. New := ''; {New is the null string }32. For Location := 1 to Length(St) Do33. If Location MOD 5 = 034. Then New := New + St[Location] + Blank35. Else New := New + St[Location];

36.Build a string from null, reverse to that of a given string37.38. New := '';39. For Location := Length(St) downto 1 Do40. New := New + St[Location];

41.Count number of vowels in a string (use set statement)42.43. Var44. St, New: String[80];45. Location, Mid: 1..80;46. Count: 0..80;47. Valid_Ch: Set of Char;48.49. Count := 0;50. Valid_Ch := ['A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o', 'u'];51. For Location := 1 to Length(St) Do52. If St[Location] IN Valid_Ch53. Then Count := SUCC(Count);54. Writeln('There were ', Count, ' vowels in ', St);

55.Convert all lower case letters in a string to upper case and visa-versa!56.57. { convert lower case letters to upper case }58. For Location := 1 to Length(St) Do59. St[Location] := UPCASE(St[Location]);60.61. { convert upper case letters to lower case }62. Valid_Ch := ['A'..'Z'];63. For Location := 1 to Length(St) Do64. If St[Location] IN Valid_Ch65. Then St[Location] := CHR(ORD(St[Location]) + 32);66.67. { Exercise: write a single structure which will convert upper68. case letters to lower case AND visa-versa }

69.Remove all the 'a', 'b' and 'c' from a given string:70.71. Type72. Bad_letters = Set of 'A'..'z';73.

Page 7: Turbo Pascal Strings

74. Var75. Remove: Bad_letters;76. Good_string: String[80];77. LCV: Integer;78.79. Remove := ['a', 'b', 'c'];80. Readln(X);81. Good_string := '';82. For LCV := 1 to Len(X) Do83. If NOT(X[LC] IN Remove)84. Then Good_string := Good_string + X[LCV];

85.Receive a real value; convert it to another real value with the integer and decimal parts interchanged:

86.87. Const88. Blank = ' ';89. Dec_pt = '.';90. Char_Zero = '0';91.92. Var93. St, New: String[80];94. Location, Mid: 1..80;95. Valid_Ch: Set of Char;96. Len, Error: Integer;97. First_real, Second_real: Real;98. Real_string, Int_string, Dec_string: String[30];99.100. Readln(First_real);101. STR(First_real :0:8, Real_string);102. Location := POS(Dec_pt, Real_string);103. Len := Length(Real_string);104. Int_string := COPY(Real_string, 1, Location - 1);105. Dec_string := COPY(Real_string, Location + 1, Len -

Location);106.107. Location := Length(Dec_string); { strip trailing

zeros }108. While Dec_String[Location] = Char_Zero Do109. Location := PRED(Location);110.111. { adjust the location marker if decimal string is all 0s }112. If Location = 0113. Then Location := 1;114.115. Dec_string := COPY(Dec_string, 1, Location);116. Real_string := Dec_string + Dec_pt + Int_string;117. VAL(Real_string, Second_real, Error);

118. Separate out pieces of a string from each other and process these pieces (they could be integer values, etc.) This is an example of a general problem called parsing a string.

a. Receive a string of integers separated by slashes (possibly with leading/trailing spaces); extract the numbers, print them one per line, and calculate their sum; no "field" is empty:

b.c. Constd. Field_separator = '/';e. Blank = ' ';f.

Page 8: Turbo Pascal Strings

g. Varh. St: String[80];i. Int_string: String[30];j. Value, Sum: Integer;k. Location: 1..80;l. Len, Error: 0..80;m. n.o. St := St + Field_separator; { add mark to terminate last

field }p. Sum := 0q. While Length(St) <> 0 Dor. Begins.t.u. { extract one field }v.w. Location := POS(Field_separator, St);x. Int_string := COPY(St, 1, Location - 1);y. DELETE(St, 1, Location);z.aa.bb. { trim leading/trailing spaces }cc.dd. Location := 1;ee. While Int_string[Location] = Blank Doff. Location := SUCC(Location);gg. DELETE(Int_string, 1, Location - 1);hh. Len := Length(Int_string);ii. Location := Len;jj. While Int_string[Location] = Blank Dokk. Location := PRED(Location);ll. DELETE(Int_string, Location + 1, Len - Location);mm.nn.oo. { convert to numeric type, print and add }pp.qq. VAL(Int_string, Value, Error);rr. Writeln(Value :4);ss. Sum := Sum + Valuett. End;uu. Writeln('----');vv. Writeln(Sum :4)

What can go wrong here? Empty fields can cause runaway string operations if we are not careful about checking for unusual cases. See an example.

ww. Same as (a), except allow "empty" fields, and leading/trailing slashes:

xx.yy. Constzz. Field_separator = '/';aaa. Blank = ' ';bbb.ccc. Varddd. St: String[80];eee. Int_string: String[30];fff. Value, Sum: Integer;

Page 9: Turbo Pascal Strings

ggg. Location: 1..80;hhh. Len, Error: 0..80;iii. jjj.kkk. St := St + Field_separator; { add mark to terminate

last field }lll. Sum := 0;mmm. While Length(St) <> 0 Donnn. Beginooo.ppp.qqq. { extract one field }rrr.sss. Location := POS(Field_separator, St);ttt. Int_string := COPY(St, 1, Location - 1);

{ Int_string could be null }uuu. DELETE(St, 1, Location);vvv.www.xxx. { trim leading/trailing spaces }yyy.zzz. Len := Length(Int_string);aaaa. Location := 1;bbbb. While (Int_string[Location] = Blank) and (Location

< Len) Docccc. Location := SUCC(Location);dddd. DELETE(Int_string, 1, Location - 1);eeee. Len := Length(Int_string);ffff. Location := Len;gggg. While (Int_string[Location] = Blank) and (Location

> 0) Dohhhh. Location := PRED(Location);iiii. DELETE(Int_string, Location + 1, Len - Location);jjjj.kkkk.llll. { convert to numeric type, print and add }mmmm.nnnn. VAL(Int_string, Value, Error);oooo. If Error = 0pppp. Thenqqqq. Beginrrrr. Writeln(Value :4);ssss. Sum := Sum + Valuetttt. Enduuuu. End;vvvv. Writeln('----');wwww. Writeln(Sum :4)

xxxx. Same as (b), except handle "dirty" fields with non-blanks before/after the numbers, as well as invalid data:

yyyy.zzzz. Program Parse;aaaaa.bbbbb.{ This program demonstrates how to "parse" a string and

separate out theccccc. important data values contained in it. It is assumed

that Line is addddd. string which contains integer values separated by /.

Typical stringseeeee. might be 34 / 45 / 789 or / / 3 / 48/ 79/ The

objective of the

Page 10: Turbo Pascal Strings

fffff. program is to separate out all the individual integer values from the

ggggg. string and process them (for example, add them up).hhhhh.iiiii. The basic idea behind the processing is to form a

WHILE loop controlledjjjjj. by the length of the string. The string will

contract as the loop runskkkkk. because pieces will be pulled from the front of the

string.lllll.mmmmm. While length string > 0 Donnnnn. 1. delete all lead spaces in stringooooo. 2. find the location of the first / in the stringppppp. 3. copy out from the string all characters from

the beginning ofqqqqq. the string up to and including / -- store this

chunk of therrrrr. string in "Piece"sssss. 4. delete the characters in Piece from the

original stringttttt. 5. counting backwards from the end of Piece, find

the last digituuuuu. in Piece (if there indeed is one)vvvvv. 6. copy out of Piece the portion of Piece which

contains onlywwwww. digits (or possibly embedded non-digits)xxxxx. 7. convert this string to a numeric value using

VALyyyyy. 8. if the conversion is successful, print this

value and add itzzzzz. to Sumaaaaaa.bbbbbb. After the loop quits, print the sum of all

the numeric valuescccccc. successfully converted from the original

string }dddddd.eeeeee. Usesffffff. crt;gggggg.hhhhhh. Constiiiiii. Line = ' / 23 / 478 /8/ 8z7

/ 2.3 /xvt/ 987 / 5996 ';jjjjjj. Sep = '/';kkkkkk. Space = ' ';llllll. Digits: Set of Char = ['0'..'9'];mmmmmm.nnnnnn. Varoooooo. X: String;pppppp. N, Error, Sum: Integer;qqqqqq. Piece: String;rrrrrr. Loc: Integer;ssssss.tttttt. Beginuuuuuu. Clrscr;vvvvvv.wwwwww. X := Line;xxxxxx. X := X + Sep; { Ensure that X ends with

a / }yyyyyy. Sum := 0;

Page 11: Turbo Pascal Strings

zzzzzz.aaaaaaa. While Length(X) > 0 Dobbbbbbb. Beginccccccc.ddddddd.eeeeeee. { Delete the lead spaces from the string

X }fffffff.ggggggg. While Pos(Space, X) = 1 Dohhhhhhh. Delete(X, 1, 1);iiiiiii.jjjjjjj.kkkkkkk. { Delete any lead non-digit characters.

Yes, this would also lllllll. delete lead spaces - but this is only

an example! }mmmmmmm.nnnnnnn. While NOT(X[1] in Digits) AND (Length(X)

>= 1) Doooooooo. Delete(X, 1, 1);ppppppp.qqqqqqq.rrrrrrr. { Find the location of the first / in X;

copy all characterssssssss. in X from the beginning of X up to and

including the / intottttttt. the string Piece; delete these

characters from the beginning of X }uuuuuuu.vvvvvvv. Loc := Pos(Sep, X);wwwwwww. Piece := COPY(X, 1, Loc);xxxxxxx. Delete(X, 1, Loc);yyyyyyy.zzzzzzz.aaaaaaaa. { Count backwards from the end of Piece

until a digit is found }bbbbbbbb.cccccccc. While NOT(Piece[Loc] in Digits) AND (Loc

> 0) Dodddddddd. Loc := Loc - 1;eeeeeeee.ffffffff.gggggggg. { Make a new copy of Piece which consists

of characters from thehhhhhhhh. beginning of Piece to the place where a

digit was located; it'siiiiiiii. possible that Loc = 0 if no digits were

encountered in Piecejjjjjjjj. (for example, if the field consists

only of spaces or of non-kkkkkkkk. digit characters) }llllllll.mmmmmmmm. Piece := COPY(Piece, 1, Loc);nnnnnnnn.oooooooo.pppppppp. { The following code can be used to see

how Piece is formed forqqqqqqqq. each field separated by /rrrrrrrr.ssssssss. If Length(Piece) > 0tttttttt. Then Writeln('piece = ''', piece, '''')

Page 12: Turbo Pascal Strings

uuuuuuuu. Else Writeln('piece = null'); }vvvvvvvv.wwwwwwww.xxxxxxxx. { Convert Piece to an integer value N }yyyyyyyy.zzzzzzzz. VAL(Piece, N, Error);aaaaaaaaa.bbbbbbbbb.ccccccccc. { If Piece is null or contains garbage,

ignore N (that is, whenddddddddd. Error > 0); otherwise, add N to Sum

and print N }eeeeeeeee.fffffffff. If Error = 0ggggggggg. Thenhhhhhhhhh. Beginiiiiiiiii. Writeln(N :4);jjjjjjjjj. Sum := Sum + Nkkkkkkkkk. End;lllllllll.mmmmmmmmm. End; { WHILE }nnnnnnnnn.ooooooooo. Writeln('----');ppppppppp. Writeln(Sum :4);qqqqqqqqq. Readln;

End.