diff options
Diffstat (limited to 'doc/gawktexi.in')
-rw-r--r-- | doc/gawktexi.in | 200 |
1 files changed, 118 insertions, 82 deletions
diff --git a/doc/gawktexi.in b/doc/gawktexi.in index 905d3dd5..fcaa01a6 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -5842,6 +5842,7 @@ used with it do not have to be named on the @command{awk} command line * Command line directories:: What happens if you put a directory on the command line. * Input Summary:: Input summary. +* Input Exercises:: Exercises. @end menu @node Records @@ -7094,10 +7095,6 @@ program for processing such data could use the @code{FIELDWIDTHS} feature to simplify reading the data. (Of course, getting @command{gawk} to run on a system with card readers is another story!) -@ignore -Exercise: Write a ballot card reading program -@end ignore - @cindex @command{gawk}, splitting fields and Assigning a value to @code{FS} causes @command{gawk} to use @code{FS} for field splitting again. Use @samp{FS = FS} to make this happen, @@ -7534,11 +7531,6 @@ decommented input, such as searching for matches of a regular expression. (This program has a subtle problem---it does not work if one comment ends and another begins on the same line.) -@ignore -Exercise, -write a program that does handle multiple comments on the line. -@end ignore - This form of the @code{getline} command sets @code{NF}, @code{NR}, @code{FNR}, @code{RT}, and the value of @code{$0}. @@ -7737,7 +7729,6 @@ each one. @xref{Close Files And Pipes}. @end ifnotdocbook @end ifnottex -@c Exercise!! @c This example is unrealistic, since you could just use system Given the input: @@ -8208,6 +8199,26 @@ Directories on the command line are fatal for standard @command{awk}; @end itemize +@node Input Exercises +@section Exercises + +@enumerate +@item +Using the @code{FIELDWIDTHS} variable (@pxref{Constant Size}), +write a program to read election data, where each record represents +one voter's votes. Come up with a way to define which columns are +associated with each ballot item, and print the total votes, +including abstentions, for each item. + +@item +@ref{Plain Getline}, presented a program to remove C-style +comments (@samp{/* @dots{} */}) from the input. That program +does not work if one comment ends on one line and another one +starts later on the same line. +Write a program that does handle multiple comments on the line. + +@end enumerate + @node Printing @chapter Printing Output @@ -8248,6 +8259,7 @@ and discusses the @code{close()} built-in function. descriptors. * Close Files And Pipes:: Closing Input and Output Files and Pipes. * Output Summary:: Output summary. +* Output exercises:: Exercises. @end menu @node Print @@ -8425,16 +8437,6 @@ The following example prints the first and second fields of each input record, separated by a semicolon, with a blank line added after each newline: -@ignore -Exercise, -Rewrite the -@example -awk 'BEGIN @{ print "Month Crates" - print "----- ------" @} - @{ print $1, " ", $2 @}' inventory-shipped -@end example -program by using a new value of @code{OFS}. -@end ignore @example $ @kbd{awk 'BEGIN @{ OFS = ";"; ORS = "\n\n" @}} @@ -8996,12 +8998,6 @@ awk 'BEGIN @{ format = "%-10s %s\n" @{ printf format, $1, $2 @}' mail-list @end example -@c !!! exercise -At this point, it would be a worthwhile exercise to use the -@code{printf} statement to line up the headings and table data for the -@file{inventory-shipped} example that was covered earlier in the @value{SECTION} -on the @code{print} statement -(@pxref{Print}). @c ENDOFRANGE printfs @node Redirection @@ -9352,7 +9348,6 @@ Note the use of quotes around the @value{FN}. Like any other redirection, the value must be a string. It is a common error to omit the quotes, which leads to confusing results. -@c Exercise: What does it do? :-) Finally, using the @code{close()} function on a @value{FN} of the form @code{"/dev/fd/@var{N}"}, for file descriptor numbers @@ -9668,6 +9663,35 @@ communications. @end itemize +@node Output exercises +@section Exercises + +@enumerate +@item +Rewrite the program: + +@example +awk 'BEGIN @{ print "Month Crates" + print "----- ------" @} + @{ print $1, " ", $2 @}' inventory-shipped +@end example + +@noindent +from @ref{Output Separators}, by using a new value of @code{OFS}. + +@item +Use the @code{printf} statement to line up the headings and table data +for the @file{inventory-shipped} example that was covered in @ref{Print}. + +@item +What happens if you forget the double quotes when redirecting +output, as follows: + +@example +BEGIN @{ print "Serious error detected!" > /dev/stderr @} +@end example + +@end enumerate @c ENDOFRANGE prnt @@ -19316,6 +19340,7 @@ comparisons use only lowercase letters. * Group Functions:: Functions for getting group information. * Walking Arrays:: A function to walk arrays of arrays. * Library Functions Summary:: Summary of library functions. +* Library exercises:: Exercises. @end menu @node Library Names @@ -20447,46 +20472,6 @@ the end of the command-line arguments. Note that the test in the condition of the @code{for} loop uses the @samp{<=} operator, not @samp{<}. -As an exercise, you might consider whether this same problem can -be solved without relying on @command{gawk}'s @code{ARGIND} variable. - -As a second exercise, revise this code to handle the case where -an intervening value in @code{ARGV} is a variable assignment. - -@ignore -# zerofile2.awk --- same thing, portably - -BEGIN @{ - ARGIND = Argind = 0 - for (i = 1; i < ARGC; i++) - Fnames[ARGV[i]]++ - -@} -FNR == 1 @{ - while (ARGV[ARGIND] != FILENAME) - ARGIND++ - Seen[FILENAME]++ - if (Seen[FILENAME] == Fnames[FILENAME]) - do - ARGIND++ - while (ARGV[ARGIND] != FILENAME) -@} -ARGIND > Argind + 1 @{ - for (Argind++; Argind < ARGIND; Argind++) - zerofile(ARGV[Argind], Argind) -@} -ARGIND != Argind @{ - Argind = ARGIND -@} -END @{ - if (ARGIND < ARGC - 1) - ARGIND = ARGC - 1 - if (ARGIND > Argind) - for (Argind++; Argind <= ARGIND; Argind++) - zerofile(ARGV[Argind], Argind) -@} -@end ignore - @node Ignoring Assigns @subsection Treating Assignments as @value{FFN}s @@ -21695,21 +21680,6 @@ $ @kbd{gawk -f walk_array.awk} @print{} a[3] = 3 @end example -@c exercise! -Walking an array and processing each element is a general-purpose -operation. You might want to consider generalizing the @code{walk_array()} -function by adding an additional parameter named @code{process}. - -Then, inside the loop, instead of simply printing the array element's -index and value, use the indirect function call syntax -(@pxref{Indirect Calls}) on @code{process}, passing it the index -and the value. - -When calling @code{walk_array()}, you would pass the name of a user-defined -function that expects to receive an index and a value, and then processes -the element. - - @c ENDOFRANGE libfgdata @c ENDOFRANGE flibgdata @c ENDOFRANGE gdatar @@ -21758,6 +21728,72 @@ A simple function to traverse an array of arrays to any depth. @end itemize +@node Library exercises +@section Exercises + +@enumerate +@item +In @ref{Empty Files}, we presented the @file{zerofile.awk} program, +which made use of @command{gawk}'s @code{ARGIND} variable. Can this +problem be solved without relying on @code{ARGIND}? If so, how? + +@ignore +# zerofile2.awk --- same thing, portably + +BEGIN @{ + ARGIND = Argind = 0 + for (i = 1; i < ARGC; i++) + Fnames[ARGV[i]]++ + +@} +FNR == 1 @{ + while (ARGV[ARGIND] != FILENAME) + ARGIND++ + Seen[FILENAME]++ + if (Seen[FILENAME] == Fnames[FILENAME]) + do + ARGIND++ + while (ARGV[ARGIND] != FILENAME) +@} +ARGIND > Argind + 1 @{ + for (Argind++; Argind < ARGIND; Argind++) + zerofile(ARGV[Argind], Argind) +@} +ARGIND != Argind @{ + Argind = ARGIND +@} +END @{ + if (ARGIND < ARGC - 1) + ARGIND = ARGC - 1 + if (ARGIND > Argind) + for (Argind++; Argind <= ARGIND; Argind++) + zerofile(ARGV[Argind], Argind) +@} +@end ignore + +@item +As a related challenge, revise that code to handle the case where +an intervening value in @code{ARGV} is a variable assignment. + +@item +@ref{Walking Arrays}, presented a function that walked a multidimensional +array to print it out. However, walking an array and processing +each element is a general-purpose operation. Generalize the +@code{walk_array()} function by adding an additional parameter named +@code{process}. + +Then, inside the loop, instead of printing the array element's index and +value, use the indirect function call syntax (@pxref{Indirect Calls}) +on @code{process}, passing it the index and the value. + +When calling @code{walk_array()}, you would pass the name of a +user-defined function that expects to receive an index and a value, +and then processes the element. + +Test your new version by printing the array; you should end up with +output identical to that of the original version. + +@end enumerate @c ENDOFRANGE flib @c ENDOFRANGE fudlib |