|
Date Published: 2002-08-26
We'll finish up today with two topics that initially might not seem to fit with everything else we've talked about concerning scalar data: handling simple input and output. I've included them here essentially for one reason: so you know what's been going on in the scripts you've been writing that read input from the keyboard and print output to the screen.
Back to Part 1
Input and Output
We'll finish up today with two topics that initially might not seem to
fit with everything else we've talked about concerning scalar data: handling
simple input and output. I've included them here essentially for one reason:
so you know what's been going on in the scripts you've been writing
that read input from the keyboard and print output to the screen.
In this section we'll talk about simple input and output, and as the book
progresses you'll learn more about input and output to disk files, culminating
on Day 15, "Working with Files and I/O."
File Handles and Standard Input and Output
First, some terminology. In the scripts you've been looking at today and
yesterday, you've used Perl code to read input from the keyboard and to
write output to the screen. In reality, the keyboard and the screen
aren't the best terms to use because, actually, you're reading from
a source called standard input, and writing to a destination called standard
output. Both of these concepts are borrowed from Unix systems, where using
pipes and filters and redirection are common, but if you're used to Windows
or the Mac, the idea of a standard input or output might not make much sense.
In all cases, when you're reading data from a source, or writing data
to a destination, you'll be working with what are called file handles.
Most often, file handles refer to actual files on the disk, but there
are instances where data might be coming from or going to an unnamed source,
for example, from or to another program such as a Web server. To generalize
data sources and destinations that are not actual files, Perl gives you built-in
file handles for standard input and standard output called STDIN and
STDOUT (there's also STDERR, for standard error, but
we'll leave that for later). These two file handles happen to include (and,
in fact, are most commonly used for) input from the keyboard and output from
the screen.
Reading a Line from Standard Input with <STDIN>
In the scripts we've seen so far in this book, there's usually been
a line for reading input from the keyboard that looks something like this:
chomp($inputline = <STDIN>);
You'll see that line a lot in Perl code, although often it occurs on multiple
lines, something like this (the two forms are equivalent):
$inputline = <STDIN>;
chomp($inputline);
You know now that $inputline is a scalar variable, and that you're
assigning something to it. But what?
The STDIN part of this line is the special built-in file handle for
standard input. You don't have to do anything to open or manage this special
file handle; it's there for you to use. In case you're wondering why
it's in all caps; that's a Perl convention to keep from confusing
file handles from other things in Perl (such as actual keywords in the language).
The angle brackets around <STDIN> are used to actually read
input from a file handle. The <> characters, in fact, are often
called the input operator. <STDIN>, therefore, means read
input from the STDIN file handle. In this particular case, where you're
assigning the <STDIN> expression to a scalar variable, Perl will
read a line from standard input and stop when it gets to a newline character
(or a carriage return on the Macintosh). Unlike in C, you don't have to
loop through the output and watch every character to make sure it's a newline;
Perl will keep track of that for you. All you need is <STDIN>
and a scalar variable to store the input line in.
Note - The definition of what a line is for <STDIN>
is actually determined by Perl's input record separator, which is a newline
character by default. On Day 9, "Pattern Matching with Regular Expressions,"
you'll learn how to change the input record separator. For now, just
assume that the end of line character is indeed the end of a line and you'll
be fine.
All this talk about input and output brings us to the somewhat amusingly named
chomp function. When you read a line of input using <STDIN>
and store it in a variable, you get all the input that was typed and the newline
character at the end as well. Usually, you don't want that newline character
there, unless you're printing the input right back out again and it's
useful for formatting. The built-in Perl chomp function, then, takes
a string as input, and if the last character is a newline, it removes that newline.
Note that chomp modifies the original string in place (unlike string
concatenation and other string-related functions, which create entire new strings
and leave the old strings alone). That's why you can call chomp
by itself on its own line without reassigning the variable that holds that string.
Note - Previous versions of Perl used a similar function for the same
purpose called chop. If you read older Perl code, you'll see
chop used a lot. The difference between chomp and chop
is that chop indiscriminately removes the last character in the string,
whether it's a newline or not, whereas chomp is safer and doesn't
remove anything unless there's a newline there. Most of the time, you'll
want to use chomp to remove a newline from input, rather than chop.
Writing to Standard Output with print
When you get input into your Perl script with <STDIN>, or from
a file, or from wherever, you can use Perl statements to do just about anything
you like with that input. The time comes, then, when you'll want to output
some kind of data as well. You've already seen the two most common ways
to do that: print and printf.
Let's start with print. The print function can take
any number of arguments and prints them to the standard output (usually the
screen). Up to this point we've only used one argument, but you can also
give it multiple arguments, separated by commas. Multiple arguments to print,
by default, will get concatenated together before they get printed:
print 'take THAT!';
print 1, 2, 3; # prints '123'
$a = 4;
print 1, ' ', $a; # prints "1 4"
print 1, " $a"; # same thing
Note - I say by default because multiple arguments to print
actually form a list, and there is a way to get Perl to print characters in
between list elements. You'll learn more about this tomorrow on Day 4,
"Working with Lists and Arrays."
I mentioned the STDOUT file handle earlier, as the way to access the
standard output. You might have noticed, however, that we've been printing
data to the screen all along with print, and we've never had to
refer to STDOUT. That's because Perl, to save you time and keystrokes,
assumes that if you use print without an explicit file handle, you
want to use standard output. In reality, the following Perl statements do exactly
the same thing:
print "Hello World!\n" ;
print STDOUT "Hello World!\n";
More about the longer version of print when you learn more about file
handles that are attached to actual files, on Day 15.
printf and sprintf
In addition to the plain old workhorse print, Perl also provides the
printf and sprintf functions, which are most useful in Perl
for formatting and printing numbers in specific ways. They work almost identically
to those same functions in C, but beware: printf is much less efficient
than print, so don't just assume you can use printf everywhere
because you're used to it. Only use printf when you have a specific
reason to do so.
As you learned yesterday, you use the printf function to print formatted
numbers and strings to an output stream, such as standard output. sprintf
formats a string and then just returns that new string, so it's more useful
for nesting inside other expressions (in fact, printf calls sprintf
to do the actual formatting).
Both printf and sprintf take two or more arguments: the first,
a string containing formatting codes, and then one or more values to plug into
those codes. For example, we've seen examples of printf that rounded
off a floating-point number to two decimal places, like this:
printf("Average (mean): %.2f", $avg);
We've seen one that truncates it to an integer, like this:
printf("%d degrees Celsius\n", $cel);
Yesterday, you also saw how to use sprintf to round a floating-point
number to two digits of precision:
$value = sprintf("%.2f", $value);
The format codes follow the same rules as the C versions (although the *
length specifier isn't supported), and can get quite complex. A simple
formatting code that you might use in Perl looks like this:
%l.px
The x part is a code referring to the type of value; in Perl you'll
be most interested in the d formatting code for printing integers,
and the f formatting code for printing floating-point numbers. The
l and the p in the formatting code are both optional. l
refers to the number of characters the value should take up in the final string
(padded by spaces if the value as printed is less than l), and p
is the number of digit precision of a floating-point number. All numbers are
rounded to the appropriate precision.
If you need to print an actual percent sign in your output, you'll need
to use two of them:
printf("%d%% humidity \n", $hum);
Here are some typical examples of how either sprintf or printf
might be used:
$val = 5.4349434;
printf("->%5d\n", $val); # 5
printf("->%11.5f\n", $val); # 5.43494
printf("%d\n", $val); # 5
printf("%.3f\n", $val); # 5.435
printf("%.1f\n", $val); # 5.4
Multiple formatting codes are interpolated left to right in the string, each
formatting code replaced by an argument (there should be an equal number of
formatting codes and extra arguments):
printf("Start value : %.2f End Value: %.2f\n", $start, $end);
In this example, if $start is 1.343 and $end is
5.33333, the statement will print this:
Start value : 1.34 End Value: 5.33
If you're unfamiliar with C's printf formatting codes, you
might want to refer to the perlfunc man page (or the printf
man page) for more details.
Another Example: Stocks
To cement what you've learned today, let's work through another simple
example that uses assignment, while loops, if conditionals,
pattern matching, input, and both print and printf statements.
This example is a stock performance tracker. All you do is enter the purchase
price of your stock and its current price, and it tells you if your investment
has lost money, made money, or broken even, and by what percentage:
% stock.pl
Enter the purchase price: 45
Enter the current price: 48
Your investment has made money.
Your return on investment is 6.7%
% stock.pl
Enter the purchase price: 45
Enter the current price: 40
Your investment has lost money.
Your return on investment is -11.1%
% stock.pl
Enter the purchase price: 45
Enter the current price: 45
Your investment has broken even.
Your return on investment is 0.0%
Stock prices must be entered as decimals (not fractions such as 14 5/8), and
must be digits. We'll check for both of these things in the script.
Listing 3.2 shows the code for our simple stock tracker. Before reading the
following description see if you can go through the code and understand what's
going on here.
Listing 3.2 The stock.pl Script
1: #!/usr/local/bin/perl -w
2:
3: $start = 0;
4: $end = 0;
5: $return = 0;
6:
7: while () {
8: print "Enter the purchase price: ";
9: chomp ($start = <STDIN>);
10:
11: print "Enter the current price: ";
12: chomp ($end = <STDIN>);
13:
14: if ($start eq '' or $end eq '' ) {
15: print "Either the purchase or current price is missing.\n";
16: next;
17: }
18:
19: if ($start =~ /\D/ or $end =~ /\D/ ) {
20: if ($start =~ /\// or $end =~ /\//) {
21: print "Please enter prices as decimal numbers.\n";
22: next;
23: } else {
24: print "Digits only, please.\n";
25: next;
26: }
27: }
28:
29: last;
30: }
31:
32: $return = ($end - $start) / $start * 100;
33:
34: if ($start > $end) {
35: print "Your investment has lost money.\n";
36: } elsif ($start < $end ) {
37: print "Your investment has made money.\n";
38: } else {
39: print "Your investment has broken even.\n";
40: }
41:
42: print "Your return on investment is ";
43: printf("%.1f%%\n", $return);
This example has three main sections: an initialization section, a section for getting and verifying input, and a section for calculating and printing the result. I'm going to skip the initialization because you've already seen a bunch of them and you know what they look like by now.
Getting and Verifying the Input
This while loop, in lines 7 to 30, is for getting the initial input from the user and is the most complex part of this script:
7: while () {
8: print "Enter the purchase price: ";
9: chomp ($start = <STDIN>);
10:
11: print "Enter the current price: ";
12: chomp ($end = <STDIN>);
13:
14: if ($start eq '' or $end eq '' ) {
15: print "Either the purchase or current price is missing.\n";
16: next;
17: }
18:
19: if ($start =~ /\D/ or $end =~ /\D/ ) {
20: if ($start =~ /\// or $end =~ /\//) {
21: print "Please enter prices as decimal numbers.\n";
22: next;
23: } else {
24: print "Digits only, please.\n";
25: next;
26: }
27: }
28:
29: last;
30: }
Initially this will look very similar to the while loop in the stats.pl script: same infinite loop, same if test with pattern matching. But there are some significant differences here. The most important difference to note is that stats.pl repeats over and over again until the user is done inputting data, whereas this script only needs two pieces of correct data and then it's done. In fact, blank input here is an error, and should be tested for. The other two errors we are checking for are nondigit input, and input made in fractional format (14 5/8, for example). We could lump the latter two together because the slash character / is a nondigit character, but printing a more specific error in that specific case makes for a more user-friendly script. Our infinite loop, then, will continue looping until we get two acceptable pieces of numeric data. Then we can break out of the loop and move on. Lines 8 through 12 enable you to look at things line by line. They prompt for the data, and store that data in the scalar variables $start and $end. Note that we prompt for both values before testing for validity, rather than doing one at a time. (One at a time would make more sense, usability-wise, but given what you know so far about Perl we would have to duplicate a lot of code, so this way is shorter). In lines 14 through 17 we test both $start and $end to see if they are empty, that is, if the user pressed Return without entering any data. If they did, we call next, which skips to the end of the loop and restarts again from the beginning, prompting again for the data. In the if statement starting in line 19 things start getting weird. Line 19 is the same test for nondigitness you saw in the stats program; this pattern checks for any input that contains data that isn't a number. This test will trap both data that is completely nonsensical for the script, along with data that might make conceptual sense but that we can't handlethe fractional numbers that I mentioned earlier (14 5/8, 101 15/16, and so on, as stock prices are sometimes listed). If the test in line 19 is true, the code in line 20 and onward begins executing. That code in-cludes the test in line 20. This test is a character pattern for a single slashwe have to backslash it here because its inside the pattern matching operator. This test, then, is here to trap those fractional numbers. If this test returns true, lines 21 and 22 are executed; we print an error (a hint, actually, and next is called to skip to the end of the loop and restart again). If the test in line 20 is not truethat is, if we have data that contains something other that a digit, but that doesn't contain a slashthen the code in lines 23 through 26 gets executed. The else clause is part of the if conditional. In an if conditional, if the test is true, the first block of code inside the curly braces is executed. If the test is false, Perl looks for the else clause, and if there is one, then that code gets executed instead. Depending on the state of the test, you'll get either one block or anothernever both. In this case, if we have nonnumeric data that doesn't contain a slash, say, "rasberry", that data will return true for the test in line 19, so the block going from lines 19 to 27 will get executed. The test in line 20, however, will be falseno slashso Perl will skip lines 20 through 22 and instead execute the else block in lines 23 through 26; print an error, and call next to again run through the same prompting-and-testing loop. The else part of the if conditional is optionalif there isn't one and the test is false, Perl just goes on executing. So if the user does indeed enter the right data, then the tests in lines 14 and 19 will be false. None of the code in lines 14 through 17 or lines 19 through 27 gets executed if the data is correct. Perl just goes straight down to line 29; last, which breaks us out of the while loop to stop asking for data. Calculating and Printing the ResultWith correct data in hand, we can go ahead and perform some arithmetic without worrying that what we've actually been given is a string or some weird combination of numbers and strings. All that is behind us now. Line 32 computes the percentage return on investment and stores it in the variable $return. 32: $return = ($end - $start) / $start * 100;
Note that we need the parentheses around the subtraction here to change the operator precedence. Without the parentheses, the division and multiplication would have been performed first, and then the subtraction, which would not have been correct. Lines 34 through 40 print our little report on how your investment is doing, and here you can see more ifs and elses. The one in the middleelsifis just a shorthand notation for nesting if conditionals inside else statements. You'll learn more about it on Day 6. Nested ifs, as this structure is called, is a way of cascading different tests and results. You'll see a lot of these sorts of structures. The tests start at the top, and if a test is true, that result is printed, and the nested if is over. Perl skips to the bottom and doesn't do any more tests. If the test is false, another test is tried until one matches or the final else at the end is the default result. In this case, there are only three possible results: $start can be less than $end, start can be greater than $end, or $start and $end can be equal. In the first two tests we check for the first two cases. The last case doesn't need a test because it's the only possible remaining outcome, so it gets caught in the final else in lines 38 through 40. The final lines, 42 and 43, print out the percentage return on investment we calculated in line 32. Here we use a printf instead of a print, so that we can format the floating-point number to have a single digit of precision. 43: printf("%.1f%%\n", $return);
In this line, %.1f is the formatting code.1 for the single digit after the decimal point, f for a floating-point number. The two percents after the formatting code (%%) are used to print out an actual percent character in the output. \n, as you know, is a newline, therefore, the result looks something like this: Your return on investment is 110.9%
A Note About Using FunctionsNow that you've learned about the print and chomp functions, as well as had a glimpse of other functions such as int and sprintf, this is a good time to go over how function calls work. If you've been paying careful attention, you might have noticed that I've been calling the print function like this: print "Hello, World!\n";
I've also been calling chomp and printf like this: chomp($input = <STDIN>);
printf("Average (mean): %.2f", $avg);
One form has parentheses around the arguments to the function, the other form doesn't. Which is correct? The answer is both. Parentheses around the arguments to a function are optional; as long as Perl can figure out what your arguments are, either form works just fine. In this book, I've used a smattering of both. My general rule is that if a function takes one argumentint or oct being good examplesI'll leave off the parentheses. If it takes multiple arguments or if its argument is an expression (printf or chomp), then I use parentheses. The print function can go either way depending on the situation. Depending on what you're familiar withand what looks right to youfeel free to pick your own rule for parenthesizing functions in your own scripts. I should mention, however, that the rule of parentheses being optional "as long as Perl can figure out what your arguments are," can occasionally be tricky to figure out, particularly with multiple arguments and when some of them are parenthesized expressions or lists. To make it even more complex, some of Perl's built-in functions are actually operators, and have a different precedence from actual function calls. (see the next section, "Going Deeper," for more information). There are rules of precedence to determine exactly how complex function calls are to be evaluated, but the safest solution, if Perl appears to be ignoring your arguments or producing weird results, is to include parentheses around all the arguments. Turning on Perl warnings will also help catch some of these problems. Going DeeperHad enough of strings and numbers yet? Want to learn more? No problem. This section has a number of other features to look at concerning scalar data before we forge on ahead to lists. Operators are all discussed in the perlop man page, whereas functions are discussed in the perlfunc man page. As I mentioned before, you can get to all these pages through the use of the perldoc command or on the Web at http://www.perl.com/pub/doc/manual/html/pod/. Useful Number and String FunctionsPerl includes quite a few built-in functions for a variety of purposes. Appendix E, "Perl Functions," contains a summary of those functions, and the perlfunc man page also describes them in further detail. In particular, Perl includes a number of useful functions for numbers and strings, including those summarized in Table 3.4. We'll explore some of these in more detail in forthcoming chapters; others you'll have to explore on your own.
Table 3.4 Number and String Functions
|
Function
|
What it does
|
|
abs
|
Absolute value
|
|
atan2
|
Arctangent
|
|
chr
|
The character represented by a number in the ASCII character set
|
|
cos
|
Cosine
|
|
exp
|
e to the power of (use ** for exponentiation)
|
|
int
|
Truncate decimal part of a float
|
|
index
|
Returns the position of the first occurrence of the substring in string
|
|
lc
|
Lowercase a string
|
|
lcfirst
|
Lowercase the first character in a string
|
|
length
|
Length (number of bytes)
|
|
log
|
Logarithm
|
|
ord
|
The number of a character in the ASCII character set
|
|
rand
|
Random number
|
|
reverse
|
Reverse a scalar
|
|
rindex
|
Reverse index (starts from end of string)
|
|
sin
|
Sine
|
|
sqrt
|
Square root
|
|
substr
|
Returns a substring starting at an offset of some length
|
|
uc
|
Uppercase a string
|
|
ucfirst
|
Uppercase the first letter in a string
|
Bitwise OperatorsPerl provides the usual set of C-like operators for twiddling bits in integers: ~, <<, >>, &, |, and ^, as well as assignment shortcuts for those operators. See the perlop man page for specifics. The cmp and <=>
OperatorsIn addition to the relational operators I described in the section on comparisons, Perl also has the <=> and cmp operators. The former is for numbers, and the latter for strings. Both return -1, 0, or 1 depending if the left operator is greater than the right, the operators are equal, or if the right operator is greater than the left, respectively. These operators are most commonly used for creating sort routines, which you'll learn more about on Day 8. Functions and Function-Like OperatorsPerl's built-in functions actually fall into two groups: functions that are functions, and operators that take one argument and masquerade as functions. The function-like operators fall in the middle of the precedence hierarchy and behave like operators in this respect (whereas function calls with parentheses always have the highest precedence). See the perlop man page under "Named Unary Operators" for a list of these functions. SummaryToday was Part 2 of everything you ever wanted to know, and probably a whole lot you didn't, about scalar data. Today you got to look at more tables of operators, in particular operators for assigning things to variables, or changing the values of variables, and for concatenating and repeating strings. You also learned about operator precedence, which determines which operators get to go first when you have an expression with lots of them in it. Along the way you also learned about pattern matching with digits and some about if and while (although you'll learn a whole lot more about them on Day 6).We finished today's lesson talking about input and output, and in particular using <STDIN> to get data into a Perl script and the various print functions to print it out again. You also learned a bit about calling functions with and without parentheses around their arguments. The built-in functions you learned about today include (see the perlfunc man page for more details about these functions):
print takes a list of comma-separated values and strings to print and outputs those values to the standard output (STDOUT). printf takes a formatting string and any number of values, and prints those values according to the codes in the formatting string. sprintf does the same thing as printf, except it returns the formatted string without printing anything. chomp with a string argument removes any trailing newlines from that string and returns the number of characters it deleted. chop is the older version of chomp; it removes the last character from the string and returns the character it removed. Q&A
-
I want to iterate over a string and count the occurrences of the letter
t. How can I do this in Perl?
-
Well, you could use a for loop and one of the string functions
to work your way through the string one character at a time, but that would
be a terrible amount of overkill (and expose you as a C programmer who still
thinks of strings as null-terminated arrays). Perl's good with strings,
and it has built-in mechanisms for finding stuff in strings so you don't
have to do perverse character-by-character comparisons. You'll learn
more about this sort of pattern matching on. Don't spend a lot of time
iterating over strings until you read that.
I don't understand why in these scripts you are testing for nonnumeric
data using \D, when we could be testing for numeric data using
\d. To me it would make more sense to just test for numbers if
you want numbers.
The problem is that both \d and \D stand for just one
character. So you could test for numeric data with \d and your
pattern would match perfectly as long as your input was 1, 2, 3, 4, and
so on, through 9. But if your input was 10 or above, that would be more
than a single character, and would not match the pattern, and, therefore,
produce an error. Theoretically you want your test to work for any
number: 1 should be just as acceptable as 11 or 111111. Later on you'll
learn how to do a pattern that matches one or more digits. For now, matching
a single nondigit character is an easy work around, the data itself can
be any number of characters but all you need is one character to be the
wrong thing.
-
Can I use printf just like I do in C?
-
Well, you can, but you should really get used to working with print
instead. The print function is more efficient, and helps cover
up things like rounding-off errors in floating-point numbers. It's
really a much better idea to use print for the vast majority of
cases and only fall back on printf for specific reasons (like rounding).
If you do use printf, you can use all the formatting codes you
can in the C version of printf except for *.
-
Why is it important that some functions are functions and some functions
are actually operators? Don't they all behave the same?
-
Nope. Functions and operators behave slightly different. Functions, for
example, have a higher precedence. And arguments to an operator might be
grouped based on precedence (giving you odd results) as well. In most cases,
however, the difference between a function and an operator should not cause
you to lie awake at night.
WorkshopThe workshop provides quiz questions to help you solidify your understanding of the material covered and exercises to give you experience in using what you've learned. Try and understand the quiz and exercise answers before you go on to tomorrow's lesson. Quiz
-
What's the difference between the postfix increment operator ($x++)
and the prefix increment operator (++$x)?
-
What does operator precedence determine? How about associativity?
-
What is the difference between the following patterns?
/d/
/\d/
/\D//d\d/
- You have the pattern /\d\d\D/. Which of the following strings
does this pattern match to?
'456'
'd55'
'55+'
'4aa''4b'
-
What is a file handle? Why do you need one?
-
Define standard input and output. What are they used for?
-
What does the chomp function do?
-
What are the differences between print, printf, and sprintf?
When would you use each one?
-
What do the following operators do?
.
**
ne
||*=
Exercises
-
Write a program that accepts any number of lines of any kind of input,
ending with a Return or Enter (similarly to how the stats.pl program
works). Return the number of lines that were entered.
-
BUG BUSTER: What's wrong with this bit of code?
-
while () {
print 'Enter a name: ';
chomp ($input = <INPUT>);
if ($input ne '') {
$names++;
}
else { last; }}
-
Write a program that accepts input as multiple words on different lines,
and combines those words into a single string.
-
Write a program that takes a string and then centers it on the screen (assume
an 80-character line, and that the string is less than 80 characters). Hint:
the length function will give you the length in characters of a
string.
-
Modify the Fahrenheit to Celsius converter program from yesterday to make
sure that the input is a valid digit. If the user enters something invalid,
loop until the input is valid. Watch out for negative numbers!
Answers
Here are the answers to the Workshop questions in the previous section.
Quiz Answers
-
The difference in prefix and postfix operators is when the variable reference
is used and when its value is evaluated. Prefix operators increment the
value before using it; postfix increments the variable afterward.
-
Operator precedence determines which parts of an expression are evaluated
first given expressions that contain other expressions. Associativity determines
the order in which operators that have the same precedence are evaluated.
-
The patterns are as follows:
-
/d/ matches the single character d.
-
/\d/ matches a single digit.
-
\/D/ matches a single nondigit character.
- /d\d/ matches a d followed by a single digit.
-
The pattern /\d\d\D/ matches two digits and one nondigit, in that
order. None of the given strings match the pattern except for '55+'.
-
A file handle is used to read data from or write data to a source or a
destination, be it a file, the keyboard, the screen, or some other device.
File handles provide a common way for Perl to handle input and output with
all those things.
-
Standard input and output are generic input sources and output destinations
(that is, not specifically from or to files). They are most commonly used
to get input from the keyboard or to print it to the screen.
-
The chomp function removes the newline from the end of a string.
If there is no newline on the end of the string, chomp does nothing.
-
The print function is the general way of printing output to the screen
or to some other output destination. The printf function prints formatted
strings to some output destination; sprintf formats a string, but
then simply returns that formatted string value instead of printing it.
- The answers are
. concatenates strings
** creates exponential numbers
ne "not equals" for strings
|| logical OR (C-style)
*= Multiply and assign; same as $x = $x * $y
Exercise Answers
-
Here's one answer:
#!/usr/local/bin/perl -w
$input = ''; # temporary input
$lines = 0; # count of lines
while () {
print 'Enter some text: ';
chomp ($input = <STDIN>);
if ($input ne '') {
$lines++;
}
else { last; }
}print "Total number of lines entered: $lines\n";
-
The file handle for standard input is STDIN, not INPUT.
-
Here's one answer:
#!/usr/local/bin/perl -w
$input = ''; # temporary input
$sent = ''; # final sentence;
while () {
print 'Enter a word: ';
chomp ($input = <STDIN>);
if ($input ne '') {
$sent .= $input . ' ';
}
else { last; }
}print "Final sentence: $sent\n";
-
Here's one answer:
#!/usr/local/bin/perl -w
$input = ""; # temporary input
$space = 0; # space around
$length = 0 ; # length of string
print 'Enter some text: ';
chomp ($input = <STDIN>);
$length = length $input;
$space = int((80 - $length) / 2);
print ' ' x $space;
print $input;
print ' ' x $space . "\n";print '*' x 80;
-
Here's one answer:
-
#!/usr/local/bin/perl -w
$fahr = 0;
$cel = 0;
while () {
print 'Enter a temperature in Fahrenheight: ';
chomp ($fahr = <STDIN>);
if ($fahr =~ /\D/ and $fahr !~ /-/) {
print "Digits only, please.\n";
next;
}
last;
}
$cel = ($fahr - 32) * 5 / 9;
print "$fahr degrees Fahrenheit is equivalent to ";printf("%.0f degrees Celsius\n", $cel);
© Copyright Pearson Education. All rights reserved.
|