// textUtility.hw.cpp
#include "textUtility2.h" // includes <iostream>
/*
* int digitCount(int n)
*
* Counts base-10 digits in the specifed integer.
*
* Parameter:
* n - the integer whose digits are to be counted.
*
* Returns:
* The number of digits in a base-10
* representation of n.
*/
int digitCount(int n)
{
if ( n < 0 )
n = 0 - n;
int numberOfDigits = 1;
while ( n >= 10 ) {
n = n / 10;
numberOfDigits++;
} // while
return numberOfDigits;
} // function digitCount
/*
* void printRightJustified(int numberToPrint,
* int columnWidth,
* ostream& output)
*
* Prints an integer with a suitable number
* of leading spaces so that it can be lined
* up in a column with a specified width,
* provided that width is at least equal to
* the number of digits in the printed number.
*
* Parameters:
* numberToPrint - the integer to print.
* columnWidth - total number of characters
* on each line of the column, including
* leading spaces. Must be at least
* equal to the number of digits in
* numberToPrint.
* output - an output stream
* Precondition: The state of output
* is true, and numberToPrint and
* its leading spaces have not yet
* been printed.
* Postcondition: The state of output
* is still true, and numberToPrint
* has been printed.
*/
void printRightJustified(int numberToPrint,
int columnWidth,
ostream& output)
{
int nonSpaceCharacters
= digitCount(numberToPrint)
+ ( ( numberToPrint < 0 ) ? 1 : 0 );
int leadingSpaces
= columnWidth - nonSpaceCharacters;
for ( int i = 0; i < leadingSpaces; i++ )
output << " ";
output << numberToPrint;
} // function printRightJustified
/*
* void printRightJustified(float numberToPrint,
* int decimalPlaces,
* int columnWidth,
* ostream& output)
*
* Prints a floating-point number in fixed-point
* format with a suitable number of leading
* spaces so that it can be lined up in a column
* with a specified width, provided that width
* is at least one greater than the total the
* number of digits in the printed number,
* including digits in whole number portion and
* the requested number of decimal places. and
* provided the total number of digits does not
* exceed the precision of the machine's
* floating-point format.
*
* Parameters:
* numberToPrint - a floating-point number
* to be printed in fixed-point format.
* The total of the number of digits in
* the whole number portion plus
* decimalPlaces should not exceed the
* precision of the machine's
* floating-point format. (If it does,
* the least significant digits will be
* meaningless.
* decimalPlaces - number of digits printed
* to the right of the decimal point.
* columnWidth - total number of characters
* on each line of the column, including
* leading spaces. Must be at least
* one greater than the total number of
* printed digits.
* output - an output stream
* Precondition: The state of output
* is true, and numberToPrint and
* its leading spaces have not yet
* been printed.
* Postcondition: The state of output
* is still true, and numberToPrint
* has been printed.
*/
void printRightJustified(float numberToPrint,
int decimalPlaces,
int columnWidth,
ostream& output)
{
bool negative = ( numberToPrint < 0 );
if ( negative )
numberToPrint = 0 - numberToPrint;
// Assertion: numberToPrint is now non-negative.
// Its original sign is remembered by boolean
// variable negative.
// Print leading spaces, whole number part,
// and decimal point:
int wholeNumberPart = (int) numberToPrint;
int nonSpaceCharacters
= digitCount(wholeNumberPart)
+ ( negative ? 1 : 0 ) // minus sign
+ 1 // decimal point
+ decimalPlaces;
int leadingSpaces
= columnWidth - nonSpaceCharacters;
for ( int i = 0; i < leadingSpaces; i++ )
output << " ";
output << (negative ? "-" : "" )
<< wholeNumberPart << ".";
// Generate fractional part:
float fractionalPart
= numberToPrint - wholeNumberPart;
for ( int i = 0; i < decimalPlaces; i++ )
fractionalPart = fractionalPart * 10;
int fractionalPartToPrint = (int) fractionalPart;
// Print fractional part with leading zeroes, if any:
int nonZeroDigits = digitCount(fractionalPartToPrint);
int leadingZeroes = decimalPlaces - nonZeroDigits;
for ( int i = 0; i < leadingZeroes; i++ )
output << "0";
output << fractionalPartToPrint;
} // function printRightJustified(float, int, int, ostream&)
/*
* void pause()
*
* Pauses the display.
* Prompts the user to press ENTER to continue.
* Lets the program continue after the user presses ENTER.
*
* Global variables:
* cin -- an istream object for interactive input.
* cin is an external variable, declared
* in library header file <iostream>.
* Precondition: The state of cin is true. (All
* previous interactive inputs were successful.)
* Postcondition: The state of cin is still true,
* cout -- an ostream object for output to the terminal.
* cout is an external variable, declared
* in library header file <iostream>.
* Precondition: The state of cout is true.
* Postcondition: The state of cout is still true.
*/
void pause()
{
cout << endl << "Press ENTER to continue....";
char x;
do {
cin.get(x);
} while ( x != '\n' ); // i.e. until reaching newline character
cout << endl;
} // function pause
/*
* bool isAscii(char x)
*
* Tests whether the specified character is
* in the ASCII range.
*
* Parameter:
* x - the character (byte) to be tested.
*
* Returns:
* true if x is in the ASCII range (0 to 127),
* false otherwise.
*/
bool isAscii(char x)
{
return( x >= 0 );
} // function isAscii
/*
* bool isAsciiDigit(char x)
*
* Tests whether the specified character is an ASCII digit.
*
* Parameter:
* x - the character (byte) to be tested.
*
* Returns:
* true if x is an ASCII digit ('0' to '9'),
* false otherwise.
*/
bool isAsciiDigit(char x)
{
return( (x >= '0' && x <= '9'));
} // function isAsciiDigit
/*
* bool isAsciiLetter(char x)
*
* Tests whether the specified character is an ASCII letter.
*
* Parameter:
* x - the character (byte) to be tested.
*
* Returns:
* true if x is an ASCII letter
* ('A' to 'Z' or 'a' to 'z'),
* false otherwise.
*/
bool isAsciiLetter(char x)
{
return( (x >= 'A' && x <= 'Z') ||
(x >= 'a' && x <= 'z'));
} // function isAsciiLetter
/*
* bool isSpace(char x)
*
* Tests whether the specified character is a space.
*
* Parameter:
* x - the character (byte) to be tested.
*
* Returns:
* true if x is a space (' '),
* false otherwise.
*/
bool isSpace(char x)
{
return ( x == ' ' );
} // function isSpace
/*
* bool isAsciiControl(char x)
*
* Tests whether the specified character is an
* ASCII control character.
*
* Parameter:
* x - the character (byte) to be tested.
*
* Returns:
* true if x is an ASCII control
* character (0 to 31, or 127),
* false otherwise.
*/
bool isAsciiControl(char x)
{
return( x < 32 || x == 127 );
} // function isAsciiControl
/*
* bool containsAsciiControl(const char text[])
*
* Tests whether the specified string contains
* ASCII control characters.
*
* Parameter:
* text - the string to be tested.
*
* Returns:
* true if text contains one or more
* ASCII control characters,
* false otherwise.
*/
bool containsAsciiControl(const char text[])
{
// Search for an ASCII control character,
// and return true when one is found:
int index = 0;
while ( text[index] != '\0' )
if ( isAsciiControl(text[index++]) )
return true;
// Assertion: If we have reached this point,
// text contains no ASCII control characters.
return false;
} // function containsAsciiControl
/*
* bool isNaturalNumber(const char text[])
*
* Tests whether the specified string represents
* a natural number, i.e. a non-negative integer.
* A string represents a natural number if, and
* only if, it contains at least one character
* and all its characters are digits.
*
* Parameter:
* text - the string to be tested.
*
* Returns:
* true if text represents a natural number,
* false otherwise.
*/
bool isNaturalNumber(const char text[])
{
if ( text[0] == '\0' )
return false;
int index = 0;
while ( text[index] != '\0' ) {
if ( ! isAsciiDigit(text[index]) )
return false;
index++;
} // while
return true;
} // function isNaturalNumber
/*
* int toDigitValue(char x)
*
* Converts a digit character to its
* intended numeric value.
*
* Parameter:
* x - the character to be converted
*
* Returns:
* the intended numeric value of the
* character x, if x is a digit.
* Returns -1 if x is not a digit.
*/
int toDigitValue(char x)
{
if ( isAsciiDigit(x) )
return ( x - '0' );
else
return -1;
} // function toDigitValue
/*
* bool parseNaturalNumber(const char text[],
* int& number)
*
* Converts a string to a non-negative integer, if the
* string consists solely of digit characters.
*
* Parameters:
* text - the string to be converted
* number - the intended natural number value.
* Precondition: none
* Postcondition: number is the intended
* integer value represented by the string,
* if the string represents a valid natural
* number value. Otherwise, number is
* unchanged.
*
* Returns:
* true if a non-negative integer was successfully
* read from text, false otherwise.
*/
bool parseNaturalNumber(const char text[],
int& number)
{
// Check validity of text:
if ( !isNaturalNumber(text) )
return false;
// Assertion: If we have reached this point,
// text represents a valid natural number.
// Read from text the natural number that
// it represents:
number = 0;
int index = 0;
while ( text[index] != '\0' ) {
number = (number * 10) + toDigitValue(text[index]);
index++;
} // while
return true;
} // function parseNaturalNumber
/*
* bool isInteger(const char text[])
*
* Tests whether the specified string represents
* an integer. A string represents an integer if,
* and only if, it consists of a string representing
* a natural number preceded by an optional leading
* minus sign.
*
* Parameter:
* text - the string to be tested.
*
* Returns:
* true if text represents an integer,
* false otherwise.
*/
bool isInteger(const char text[])
{
if ( text[0] == '\0' )
return false;
if ( text[0] == '-' )
text = text + 1;
return isNaturalNumber(text);
} // function isInteger
/*
* int compare(const char text1[], const char text2[])
*
* Determines the lexicographical ordering of
* two C-strings.
*
* Parameters:
* text1 - a C-string
* text2 - another C-string
*
* Returns:
* An integer < 0, if text1 precedes
* text2 in a lexicographical ordering;
* an integer > 0, if text2 precedes
* text1 in a lexicographical ordering; or
* 0, if text1 equals text2.
*/
int compare(const char text1[], const char text2[])
{
int index = 0;
while ( (text1[index] == text2[index])
&& (text1[index] != '\0') )
index++;
return (text1[index] - text2[index]);
} // function compare
/*
* bool isForbinInt(const char text[])
*
* Tests whether the specified string represents
* a value of type int on forbin. A string represents
* such a value if, and only if, it consists of a
* string representing an integer and that integer is
* within the int range on forbin, i.e. within the
* range -2147483648 to 2147483647, inclusive.
*
* Parameter:
* text - the string to be tested.
*
* Returns:
* true if text represents an int on forbin.
* false otherwise.
*/
bool isForbinInt(const char text[])
{
if ( ! isInteger(text) )
return false;
bool negative = ( text[0] == '-' );
if ( negative )
text = text + 1;
while ( text[0] == '0' )
text = text + 1;
int index = 0;
while ( text[index] != 0 )
index++;
int length = index;
if ( length > 10 )
return false;
if ( length < 10 )
return true;
if ( negative && compare(text, "2147483648") <= 0 )
return true;
if ( compare (text, "2147483648") < 0 )
return true;
return false;
} // function isForbinInt
/*
* bool parseForbinInt(const char text[],
* int& number)
*
* Converts a string to an int value, if the
* string represents an integer within forbin's
* int range, i.e. within the range
* -2147483648 to 2147483647, inclusive.
*
* Parameters:
* text - the string to be converted
* number - the intended int value.
* Precondition: none
* Postcondition: number is the intended
* integer value represented by the string,
* if the string represents a valid forbin
* int value. Otherwise, number is
* unchanged.
*
* Returns:
* true if a non-negative integer was successfully
* read from text, false otherwise.
*/
bool parseForbinInt(const char text[],
int& number)
{
// Check validity of text:
if ( !isForbinInt(text) )
return false;
// Assertion: If we have reached this point,
// text represents a valid forbin int.
bool negative = ( text[0] == '-' );
if ( negative )
text = text + 1;
parseNaturalNumber(text, number);
if ( negative )
number = 0 - number;
return true;
} // method parseForbinInt