Study guide: The ins and outs of standard input/output

Brush up on Java terms, learn tips and cautions, review homework assignments, and read Jeff's answers to student questions

Glossary of terms

standard error device
That part of the operating system that controls where a program sends error messages.
standard I/O
A standardized input/output mechanism that originates from the Unix operating system. It uses devices for inputting and outputting data.
standard input device
That part of the operating system that controls from where a program receives its input.
standard output device
That part of the operating system that controls where a program sends its output.

Tips and cautions

These tips and cautions will help you write better programs and save you from agonizing over why the compiler produces error messages.

Tips

  • When using java.exe to run an application, you can redirect standard output, so that output arrives at a file instead of the screen. You accomplish that task by specifying the greater-than-sign (>) character followed by a filename after java.exe on a command line.
  • When using java.exe to run an application, you can redirect standard input, so that input originates from a file instead of the keyboard. You accomplish that task by specifying the less-than-sign (<) character followed by a filename after java.exe on a command line.
  • Use System.err instead of System.out for outputting error messages. After all, a user might become confused if a problem occurs in a program and no error message appears on the screen because the message is sent to the standard output device -- which has been redirected from the screen to a file.

Cautions

  • System.in.read() does not return user-entered integer numbers. Instead, it returns either a key's 7-bit ASCII code or a file's 8-bit byte.
  • System.in.read() can throw exceptions.

Homework

Because the last several articles have covered a lot of detailed material, this shorter article provides a brief respite. As an added bonus, there is no homework.

Answers to last month's homework

Last month, I presented the first of several Java 101 quizzes. Each quiz is designed to get you thinking about concepts introduced in the Java 101 course and to help prepare you for certification. This month, those questions are answered. Check out the following answers to see how well you're doing!

  1. Write an application that prints out its command line arguments.
  2. To answer that question, Listing 6 presents source code to an application called PrintArgs.

    Listing 6. PrintArgs.java

    // PrintArgs.java
    class PrintArgs
    {
       public static void main (String [] args)
       {
          for (int i = 0; i < args.length; i++)
               System.out.println (args [i]);
       }
    }
    
    

    To run PrintArgs, issue a command line like java PrintArgs First Second Third.

  3. What is wrong with the java calculator 4 * 3 command line, and why?
  4. The complier interprets the asterisk character, *, as a wildcard character -- a character that represents all files in the current directory when java runs -- instead of an asterisk symbol. As such, the command line arguments passed to calculator are not 4, *, and 3. Instead, the command line arguments are 4, a list of file names for all files in the directory from where java runs, and 3. To fix that problem, surround the asterisk with double-quote characters (e.g., java calculator 4 "*" 3).

  5. What is a comment, and what kinds of comments does Java support?
  6. A comment is nothing more than source code documentation set apart from program source code by the use of certain symbols. Java supports multiline, single-line, and doc comments.

  7. True or false: multiline comments can be nested.
  8. False: multiline comments cannot be nested.

  9. What is an identifier, and what criteria does Java use to determine which identifiers are legal?
  10. An identifier is a sequence of characters that names a variable, method, class, interface, or package. Java classifies a legal identifier as a sequence of characters beginning with a letter, a currency character, or a connecting character, and continuing with letters, digits, currency characters, and connecting characters.

  11. Are true, false, and goto considered keywords?
  12. true, false, and goto are reserved words because they cannot be used to name variables, methods, and so on. However, only goto is considered a keyword because true and false represent literals; and keywords are not also literals.

  13. What is the purpose of a data type?
  14. A data type describes the internal binary representation of a data item along with any operations that can be legally applied to that representation.

  15. List the names of Java's primitive data types.
  16. The names of Java's primitive data types are Boolean, byte integer, character, double-precision floating-point, floating-point, integer, long integer, and short integer. These data types are specified in source code by using Java's boolean, byte, char, double, float, int, long, and short keywords.

  17. True or false: Java's various integer data types can be used to represent both signed and unsigned numbers.
  18. True: Java's various integer data types represent both signed and unsigned numbers. For example, a byte integer data type can represent an integer ranging from -128 to 127 (inclusive).

  19. What is the default data type of a floating-point literal?
  20. The default data type of a floating-point literal is double-precision floating-point.

  21. Is a value of a primitive data type considered to be an object?
  22. A value of a primitive data type is not considered an object. Note: A literal string is not a value of a primitive data type. Instead, it represents an object.

  23. What is the difference between a primitive data type and a reference data type?
  24. A primitive data type is a predefined data type named by a reserved word. Values of primitive data types are not objects. In contrast, a reference data type is a developer-defined data type -- a class. Objects can be created from reference data types.

  25. What is a variable?
  26. A variable is a storage location that contains a data item.

  27. Declare a pair of integer nonarray variables (in one declaration) and initialize one variable to the literal 1.
  28. int i, j = 1;
    
    
  29. How do you obtain the length of an array variable?
  30. You obtain the length of an array variable by specifying .length. For example, assuming you have an array called animals, animals.length returns animal's length (also known as number of array elements).

  31. What is the difference between an array variable and a nonarray variable?
  32. An array variable contains multiple storage locations, where an integer number represents each storage location. A single data item can be stored in each storage location. In contrast, a nonarray variable consists of a single storage location, and only one data item can be stored there.

  33. What is a constant, and how does it differ from a variable?
  34. Unlike variables, which can be read from and written to, a constant is a read-only variable. Specify it by prefixing the keyword final to the variable's data type.

  35. Declare a constant for the mathematical concept of PI.
  36. final double PI = 3.14159;
    
    
  37. What is an operator?
  38. An operator is a combination of characters that identifies a data operation, such as addition.

  39. What is the name given to the entity or entities that are operated on by an operator?
  40. The name given to the entity or entities that are operated on by an operator is operand.

  41. If an operator operates on only one entity, that operator is known as what?
  42. A unary operator operates on only one entity.

  43. If an operator operates on a pair of entities, that operator is known as what?
  44. A binary operator operates on a pair of entities.

  45. How many ternary operators does Java have? Please identify those operators.
  46. Java only has one ternary operator known as the conditional operator.

  47. What is an overloaded operator?
  48. An overloaded operator is an operator that performs different operations based on its operands' data types. For example, Java's + operator is used to perform addition when its operands are numeric or string concatenation when one or both operands are strings.

  49. Does Java provide any overloaded operators?
  50. Java's addition/string concatenation operator, +, is an example of an overloaded operator. Furthermore, the bitwise AND/Boolean AND operator, &; bitwise inclusive OR/Boolean inclusive OR operator, |; and bitwise exclusive OR/Boolean exclusive OR operator, ^, are overloaded. There are a few other overloaded operators, but I'll leave it as an exercise for you to find them.

  51. Can a developer overload an operator?
  52. Unlike C++, Java doesn't allow developers to overload operators.

  53. What kind of operator is the minus sign?
  54. The minus sign is a unary operator when used for negation (e.g., -6) and a binary operator when used for subtraction (e.g., 5 - 3).

  55. What symbols does Java use to represent the bitwise AND, conditional, and reference data type-checking operators?
  56. Java uses & to represent bitwise AND, ? : to represent conditional, and instanceof to represent reference data type-checking.

  57. What is the difference between the predecrement and postdecrement operators?
  58. The predecrement operator decrements its operand's value by one and then returns the new value. In contrast, the postdecrement operator returns its operand's value before incrementing the operand value. (Java accomplishes that task by storing the operand's value in a temporary memory location, incrementing the operand's value, and returning the original value from the temporary memory location.)

  59. What happens when 6.3 is divided by 0.0?
  60. When 6.3 is divided by 0.0 (as in 6.3 / 0.0), a special value representing +Infinity returns.

  61. What is the difference between the logical AND and Boolean AND operators?
  62. The logical AND operator, &&, evaluates its left operand. If the value of that operand is false, && doesn't evaluate the right operand. That behavior is known as short circuiting. In contrast, the Boolean AND operator, &, evaluates both operands.

  63. What is the fastest operator for multiplying by powers of 2?
  64. The fastest operator for multiplying by powers of 2 is the bitwise shift left operator. For example, x = x << 1; is the same as x = x * 2;.

  65. What is the purpose of a cast operator?
  66. The cast operator converts its operand's data type to another data type.

  67. Is byte b = 40; b = b | 0x31; legal Java code? Why or why not?
  68. The above code is not legal because 0x31 is an integer literal and b is a byte integer. b | 0x31 returns a value of type integer. Because an integer value is 32 bits and a byte integer variable can only hold 8 bits, some bits will be lost when converting from integer to byte integer. Whenever bits will be lost, a cast operator is required. To fix the above code, specify b = (byte) (b | 0x31);.

  69. What is an expression?
  70. An expression is a sequence of operators and operands -- constructed according to the Java language's syntax -- that evaluates to a specific data type's single value.

  71. What is precedence, and how can precedence be changed?
  72. Precedence is a predefined evaluation order. Parentheses are used to change precedence. For example, 6 + 3 * 2 first evaluates 3 * 2 and then adds that result to 6. The final result is 12. You can change the precedence so that multiplication follows addition by using parentheses as follows: (6 + 3) * 2. Now, 6 + 3 evaluates first. The final result is 18.

  73. What is the difference between the expression 'A' + 6 and the expression "A" + 6?
  74. The expression 'A' + 6 evaluates to the integer value 71. The expression "A" + 6 evaluates to the string A6.

  75. What is a statement?
  76. A statement is a source code construct that declares one or more variables, assigns an expression's result to a variable, repeatedly executes other statements in a loop, controls a loop, makes a decision, and so on.

  77. What is a block?
  78. Block is a synonym for compound statement -- zero or more statements surrounded by brace characters.

  79. Explain what is meant by the dangling-else problem.
  80. The dangling-else problem refers to improperly matching elses to the appropriate ifs in decision statements.

  81. True or false: a switch statement can be specified with a numeric expression that evaluates to long integer.
  82. False: It is illegal to specify a long integer numeric expression in a switch statement. That is probably due to the Java Language Specification treating long integers as two variables of 32 bits each. Because of that fact, a JVM doesn't have to read or write a long integer variable in a single 64-bit atomic operation. Instead, it can use two 32-bit operations. If long integer numeric expressions could be used with switch statements, imagine what would happen if two threads of execution are running and a second thread writes a new value to the long integer between the first read and the second read. Chaos would result!

  83. What is the difference between an entry condition and an exit condition loop?
  84. Loops evaluate Boolean expressions to determine whether they keep iterating. An entry condition loop (such as a while loop) evaluates the Boolean expression before executing the body of the loop. In contrast, an exit condition loop (such as a do-while loop) evaluates the Boolean expression after executing the body of the loop.

  85. True or false: a do-while loop is known as an entry condition loop.
  86. False: a do-while loop is known as an exit condition loop because the Boolean expression is evaluated after the loop's body has executed.

  87. What is wrong with int i = 0; while (true); System.out.println (i++);
  88. The semicolon in while (true); forms the problem in the code above. If that semicolon is left as is, the loop is infinite and does absolutely nothing. Even after you remove the semicolon, the loop is still infinite -- though that loop can print out values of i. However, the presence of the infinite loop, which cannot be terminated (apart from pressing Ctrl+C), still constitutes a problem.

  89. How can you specify a for loop that never stops iterating -- an infinite loop?
  90. for (; ;) System.out.println ("Looping forever");
    
    
  91. True or false: the first and third clauses in a for loop can consist of more than a single expression.
  92. The answer is true, which the following code illustrates:

    for (int i = 2, j = 3; i < 10; i++, j++)
         System.out.println (i + ", " + j);
    
    
  93. True or false: the first (initialization) clause in a for loop executes once for each iteration.
  94. False: the for loop's initialization clause executes once for the entire loop.

  95. What is the purpose of a labeled break statement?
  96. A labeled break statement causes execution to break out of nested loops. It is also used to break out of nested switch statements or combinations of nested loops/nested switch statements.

  97. What is the purpose of a labeled continue statement?
  98. A labeled continue statement terminates the current iteration of either a single loop or several loops (in a nested situation).

  99. Write a Java application that reads a floating-point number from standard input, assumes that number represents a temperature in degrees Celsius, converts that temperature to Fahrenheit, and outputs the result.
  100. Listing 7 provides the answer by presenting source code to an application called C2F.

    Listing 7. C2F.java

    // C2F.java
    class C2F
    {
       public static void main (String [] args) throws java.io.IOException
       {
          System.out.print ("Please enter a temperature in degrees Celsius: ");
          double celsius = 0.0;
          boolean inDecimal = false;
          int numDecimalDigits = 0;
          int ch;
          while ((ch = System.in.read ()) != '\n')
             if (ch >= '0' && ch <= '9')
             {
                 celsius *= 10;
                 celsius += ch - '0';
                 if (inDecimal)
                     numDecimalDigits++;
             }
             else
             if (ch == '.')
             {
                 if (inDecimal)
                 {
                     System.err.println ("Too many decimals.");
                     return;
                 }
                 inDecimal = true;
             }
             else
                 break;
          if (numDecimalDigits != 0)
              celsius /= Math.pow (10, numDecimalDigits);
          // Note: Math.pow calculates 10 to the power of numDecimalDigits.
          // I'll have more to say about Math.pow in an upcoming article.
          System.out.println ("Degrees Fahrenheit = " + (9.0 / 5.0 * celsius + 32.0));
       }
    }
    
    

    C2F handles a number's fractional part by counting the number of digits following the decimal point. After the last digit has been read, and if the count is not zero, the number is divided by 10 times that count.

    C2F isn't perfect! What happens if you enter a single decimal point? I'll leave it as an exercise for you to figure out what to do about that situation.