// ACMIO.java
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PushbackReader;
import java.text.NumberFormat;
/*****************************************************************************
* The ACMIO
class has methods for reading some primitive data values
* from the keyboard and text files, and it has methods to set fieldwidth
* and precision in formatting Strings for output. The class was designed
* for use in the ACM Mid-Central Regional Competition, November 6, 1999.
* See the sample program ACMIOTest.java and sample input file t.txt.
*
ACMIO fileIn = new ACMIO("problem1.in");
* ACMIO stdin = ACMIO.getStdin();
* getChar()
reads the next character, and
*
* getLine()
reads a whole line.
*
* intRead() andstringRead()
.
* Note all start with a lowercase letter. Method stringRead()
reads
* the longest String with no whitespace. There are also methods with "ln"
* added to the end: intReadln(), longReadln(), doubleReadln(),
* charReadln()
and stringReadln()
, which all skip the rest
* of the line.getLine()
and
* stringReadln().
* Both end up after the end of a line, but getLine()
returns the
* rest of the current line, and stringReadln()
skips all whitespace,
* possibly through several empty lines, and skips to the end of the line
* afterthe first sequence of non-whitespace characters it finds.isEOLN()
and
* isEOF()
, which read ahead to see if the end of a line or the
* end of the file is next.skipBlanks()
,
* skipWhitespace()
, and skipLine()
.String format(long l, int minimumWidth)
* String format(Object o, int minimumWidth)
* String format(double d, int minimumWidth)
* String format(double d, int minimumWidth, int precision)
*
where a positive minimumWidth
means right-justify and negative
* means left-justify, and both are in a field of at least |minimumWidth
|
* columns.
*
Explicit overloadings for the justification are only given for numbers
* and for objects, but anything can be converted to a String Object by concatenating
* it with the empty String: "" + (anything). Examples:
*
format(123.45678, 7, 2)
returns " 123.46"
, with one
* blank on the left.
* format(123.45678, -7, 2)
returns "123.46 "
, with
* one blank on the right.
* format(-1234, 8)
returns " -1234"
, with
* three blanks on the left.
* format("abc", -5)
returns "abc "
, with two
* blanks on the right.
*
* @author
* Andrew Harrington (anh@cs.luc.edu)
*
* @version
* Sept 16, 1999
****************************************************************************/
public class ACMIO
{
private static ACMIO stdin = null;
private PushbackReader in;
final static int EOF = -1; // Returned by in.read() at EOF
/**
* Construct an ACMIO to read from a file.
* @param
* filename
file to read from.
*
ACMIO
object that reads from System.in
.
* @param none
* @return
* ACMIO
object that reads from System.in
**/
public static ACMIO getStdin() {
if (stdin == null)
stdin = new ACMIO();
return stdin;
}
/**
* Read and discard whitespace: blanks, tabs, and newlines.
* @param none
**/
public void skipWhitespace()
{
unread(pastWhitespace());
}
/**
* Read and discard blanks.
* @param none
**/
public void skipBlanks()
{
int next = read();
while (' ' == next)
next = read();
unread(next);
}
/**
* Read and discard the rest of the current input line.
* @param none
**/
public void skipLine()
{
int next = read();
while (next != '\n' && next != EOF)
next = read();
}
/**
* Read until the end of the current line.
* @param none
* @return
* a String
with all characters other that '\r' or '\n'
* until the end of the line, or end-of-file if that comes first.
**/
public String getLine()
{
StringBuffer buffer = new StringBuffer(80);
int next = read();
while (next != '\n' && next != EOF) {
if (next != '\r')
buffer.append((char)next);
next = read();
}
return buffer.toString();
}
/**
* Read a character.
* @param none
* @return
* a character read
*
* double
number.
* @param none
* @return
* a double number that's been read
* Double.valueOf
.
* doubleRead()
with
* skipLine()
called just before returning.
**/
public double doubleReadln()
{
double answer = doubleRead();
skipLine();
return answer;
}
/**
* Read an int value.
* @param none
* @return
* an int that has been read
* Integer.parseInt
.
* intRead()
with
* skipLine()
called just before returning.
**/
public int intReadln()
{
int answer = intRead();
skipLine();
return answer;
}
/**
* Read a long value.
* @param none
* @return
* a long value that has been read
* Long.parseInt
.
* longRead()
with
* skipLine()
called just before returning.
**/
public long longReadln()
{
long answer = longRead();
skipLine();
return answer;
}
/**
* Read the next whitespace-delimited String
.
* @param none
* @return
* a String
of non-whitespace characters read
* String
,
* and skip the rest of the line it is on.
* @param none
* @return
* a String
of non-whitespace characters read
* isEOF()
**/
public boolean isEOLN()
{
int next = read();
unread(next);
return (next == '\n') || (next == '\r' || next == EOF);
}
//private input methods ------------------------------------------------------------
private static void badExit(String errMsg) {
// abort with message
System.err.println("Aborting -- " + errMsg);
System.exit(-1);
}
private int read()
// Read and return the next character or abort.
{
int next = 0;
try
{
next = in.read();
}
catch (IOException e)
{
badExit("File reading error! " + e.getMessage());
}
return next;
}
private void unread(int next)
// Unread next or abort.
{
if (next == EOF) return;
try
{
in.unread(next);
}
catch (IOException e)
{
badExit("File unreading error! " + e);
}
}
private int findDigits(int next, StringBuffer buffer)
// append any digits, starting with next to buffer, return first non-digit
{
while (Character.isDigit((char)next)) {
buffer.append((char)next);
next = read();
}
return next;
}
private int findInteger(int next, StringBuffer buffer)
// append any sign+digits, starting with next to buffer,
// return first char not matching pattern
{
if (next == '+') next = read();
if (next == '-') {
buffer.append('-');
next = read();
}
return findDigits(next, buffer);
}
private int pastWhitespace()
// Read and discard whitespace: blanks, tabs, and newlines.
// return first non-whitespace char
{
int next = read();
while (Character.isWhitespace((char)next))
next = read();
return next;
}
// String formatting routines ----------------------------------------------
private static NumberFormat numForm = NumberFormat.getNumberInstance();
/**
* Format a double as a String with a specified format.
* @param d
* the number to be printed
* @param minimumWidth
* |minimumWidth| is the minimum number of characters in the entire
* output, and the positive or negative sign indicates right or left
* justification.
* @param fractionDigits
* the number of digits to print, with rounding, on the right side
* of the decimal point. A negatine fractionDigits is treated like 0.
* No decimal point is printed if fractionDigits
is 0.
**/
public static String format(double d, int minimumWidth, int fractionDigits)
{
numForm.setGroupingUsed(false); // no commas
if (fractionDigits < 0) fractionDigits = 0;
numForm.setMinimumFractionDigits(fractionDigits);
numForm.setMaximumFractionDigits(fractionDigits);
return format(numForm.format(d), minimumWidth);
}
/**
* Create a left or right justified String from an Object
.
* @param o
* the Object to be printed
* @param minimumWidth
* |minimumWidth| is the minimum number of characters in the entire
* output, and the positive or negative sign indicates right or left
* justification.
**/
public static String format(Object o, int minimumWidth)
{
String s = o.toString();
int nBlanks = Math.abs(minimumWidth) - s.length();
if (nBlanks <= 0) return s;
String BLANK40 = " ";
String pad = "";
while (nBlanks >= 40) {
pad += BLANK40;
nBlanks -= 40;
}
pad += BLANK40.substring(0,nBlanks);
if (minimumWidth > 0)
return pad+s;
else
return s+pad;
}
/**
* Create a left or right justified String from a double value.
* @param d
* the number to be printed
* @param minimumWidth
* |minimumWidth| is the minimum number of characters in the entire
* output, and the positive or negative sign indicates right or left
* justification.
**/
public static String format(double d, int minimumWidth)
{
return format(""+ d, minimumWidth);
}
/**
* Create a left or right justified String from a long value.
* @param n
* the number to be printed
* @param minimumWidth
* |minimumWidth| is the minimum number of characters in the entire
* output, and the positive or negative sign indicates right or left
* justification.
**/
public static String format(long n, int minimumWidth)
{
return format("" + n, minimumWidth);
}
}