You are on page 1of 15

E

C Legacy Code
Topics
Well use a signal I have tried
and found far-reaching and
easy to yell. Waa-hoo!
Zane Grey

It is quite a three-pipe
problem.
Sir Arthur Conan Doyle

But yet an union in


partition.

OBJECTIVES
In this chapter you will learn:

William Shakespeare

To redirect keyboard input to come from a le and


redirect screen output to a le.
To write functions that use variable-length argument
lists.

To process command-line arguments.

To process unexpected events within a program.

To allocate memory dynamically for arrays, using


C-style dynamic memory allocation.
To resize memory dynamically allocated, using
C-style dynamic memory allocation.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Appendix E C Legacy Code Topics

Self-Review Exercises
E.1

Fill in the blanks in each of the following:


a) Symbol
redirects input data from the keyboard to come from a file.
ANS: redirect input (<).
b) The
symbol is used to redirect the screen output to be placed in a file.
ANS: redirect output (>).
c) The
symbol is used to append the output of a program to the end of a file.
ANS: append output (>>).
is used to direct the output of a program as the input of another prod) A(n)
gram.
ANS: pipe (|).
e) A(n)
in the parameter list of a function indicates that the function can receive a variable number of arguments.
ANS: ellipsis (...).
f) Macro
must be invoked before the arguments in a variable-length argument list can be accessed.
ANS: va_start.
g) Macro
is used to access the individual arguments of a variable-length argument list.
ANS: va_arg.
h) Macro
performs termination housekeeping in a function whose variable
argument list was referred to by macro va_start.
ANS: va_end.
i) Argument
of main receives the number of arguments in a command line.
ANS: argc.
j) Argument
of main stores command-line arguments as character strings.
ANS: argv.
k) The UNIX utility
reads a file called
that contains instructions
for compiling and linking a program consisting of multiple source files. The utility recompiles a file only if the file (or a header it uses) has been modified since it was last
compiled.
ANS: make, Makefile.
l) Function
forces a program to terminate execution.
ANS: exit.
m) Function
registers a function to be called upon normal termination of the
program.
ANS: atexit.
n) An integer or floating-point
can be appended to an integer or floatingpoint constant to specify the exact type of the constant.
ANS: suffix.
o) Function
can be used to register a function to trap unexpected events.
ANS: signal.
p) Function
generates a signal from within a program.
ANS: raise.
q) Function
dynamically allocates memory for an array and initializes the elements to zero.
ANS: calloc.
r) Function
changes the size of a block of dynamically allocated memory.
ANS: realloc.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises

s) A(n)
is an entity containing a collection of variables that occupy the same
memory, but at different times.
ANS: union.
t) The
keyword is used to introduce a union definition.
ANS: union.

Exercises
E.2

Write a program that calculates the product of a series of integers that are passed to function
using a variable-length argument list. Test your function with several calls, each with a different number of arguments.

product

ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

// Exercise E.2 Solution: exE_02.cpp


#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::ios;
#include <cstdarg>
using std::va_list;
// function with variable length argument list
int sum( int, ... );
int main()
{
// values to sum
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
// display integer values
cout << "a = " << a << ", b = " << b << ", c = " << c << ", d = " << d
<< ", e = " << e << "\n\n";
// call sum with
cout << "The sum
<< "\nThe sum
<< "\nThe sum
<< "\nThe sum
<< endl;
return 0;
} // end main

different number of arguments in each


of a and b is: " << sum( 2, a, b )
of a, b, and c is: " << sum( 3, a, b,
of a, b, c, and d is: " << sum( 4, a,
of a, b, c, d, and e is: " << sum( 5,

call
c )
b, c, d )
a, b, c, d, e )

// function main has variable length argument list


// sums integers passed as arguments
int sum( int i, ... )
{
int total = 0; // sum of integers

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

4
41
42
43
44
45
46
47
48
49
50
51

Appendix E C Legacy Code Topics

va_list ap; // variable length argument list


va_start( ap, i ); // invoke macro to access arguments
// calculate total
for ( int j = 1; j <= i; j++ )
total += va_arg( ap, int );
va_end( ap ); // perform termination housekeeping
return total; // return sum of arguments
} // end function sum

a = 1, b = 2, c = 3, d = 4, e = 5
The
The
The
The

E.3

sum
sum
sum
sum

of
of
of
of

a and
a, b,
a, b,
a, b,

b is: 3
and c is: 6
c, and d is: 10
c, d, and e is: 15

Write a program that prints the command-line arguments of the program.


ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// Exercise E.3 Solution: exE_03.cpp


#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::ios;
int main( int argc, char *argv[] )
{
// display arguments given to program at command line
cout << "The command line arguments are:\n";
for ( int i = 0; i < argc; i++ )
cout << argv[ i ] << ' ';
return 0;
} // end main

C:\>exE_03.exe arg1 arg2 arg3


The command line arguments are:
C:\exE_03.exe arg1 arg2 arg3

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises

E.4
Write a program that sorts an integer array into ascending order or descending order. The
program should use command-line arguments to pass either argument -a for ascending order or -d
for descending order. [Note: This is the standard format for passing options to a program in UNIX.]
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

// Exercise E.4 Solution: exE_04.cpp


#include <iostream>
using std::cout;
using std::cin;
#include <iomanip>
using std::setw;
const int SIZE = 100; // size of integer array
// function prototype
void swap( int * const, int * const );
int main( int argc, char *argv[] )
{
int a[ SIZE ]; // holds integers input by user
bool order; // sort in ascending or descending order
// tell user if improper arguments were passed
if ( argc != 2 )
cout << "Usage: exE_04 -option\n";
else
{
// ask user to enter integers to be sorted
cout << "Enter up to " << SIZE << " integers (EOF to end input): ";
int count;
// store input integers until 100 elements or end-of-file entered
for ( count = 0; !( cin.eof() ) && count < SIZE; count++ )
cin >> a[ count ];
// count is incremented before for loop continuation fails
count--;
// set order based on command-line argument
order = ( argv[ 1 ][ 1 ] == 'd' ) ? true : false;
// loop through array and swap elements as needed
for ( int i = 1; i < count; i++ )
for ( int j = 0; j < count - 1; j++ )
// swap in descending order if that option specified
if ( order )
{
if ( a[ i ] > a[ j ] )
swap( &a[ i ], &a[ j ] );
} // end outer if
else // swap in ascending order if that option specified

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

6
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

Appendix E C Legacy Code Topics

if ( a[ i ] < a[ j ] )
swap( &a[ j ], &a[ i ] );
// display sorted array
cout << "\n\nThe sorted array is:\n";
for ( int j = 0; j < count; j++ )
cout << setw( 3 ) << a[ j ];
cout << '\n';
} // end else
return 0;
} // end main
// function that swaps two integers
void swap( int * const xPtr, int * const yPtr )
{
int temp; // temporary variable used for swapping
// swap the two integers
temp = *xPtr;
*xPtr = *yPtr;
*yPtr = temp;
} // end function swap

C:\>exE_04.exe -a
Enter up to 100 integers (EOF to end input): 5 8 34 -2 65 7 4
^Z
The sorted array is:
-2 4 5 7 8 34 65
C:\>exE_04.exe -d
Enter up to 100 integers (EOF to end input): 77 2 -8 9 44 8 76 41 99
^Z
The sorted array is:
99 77 76 44 41 9 8

2 -8

E.5
Read the manuals for your system to determine what signals are supported by the signalhandling library (<csignal>). Write a program with signal handlers for the signals SIGABRT and SIGINT. The program should test the trapping of these signals by calling function abort to generate a
signal of type SIGABRT and by pressing Ctrl+C to generate a signal of type SIGINT.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
E.6

Write a program that dynamically allocates an array of integers using a function from
not the new operator. The size of the array should be input from the keyboard. The elements of the array should be assigned values input from the keyboard. Print the values of the array.
Next, reallocate the memory for the array to half of the current number of elements. Print the values
remaining in the array to confirm that they match the first half of the values in the original array.
<cstdlib>,

ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

// Exercise E.6 Solution: exE_06.cpp


#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::ios;
#include <iomanip>
using std::setw;
#include <cstdlib>
using std::calloc;
using std::realloc;
int main()
{
int count; // number of elements in the array
int *array; // pointer to the array
// ask user for size of array
cout << "This program dynamically allocates an array of integers."
<< "\nEnter the number of elements in the array: ";
cin >> count;
// allocate memory
array = static_cast< int * >( calloc( count, sizeof( int ) ) );
// initialize elements of array with user-entered data
for ( int i = 0; i < count; i++ )
{
cout << "Enter an integer: ";
cin >> array[ i ];
} // end for
// display the original array
cout << "\nThe elements of the array are:\n";
for ( int j = 0; j < count; j++ )
cout << setw( 3 ) << array[ j ];
// reallocate to half the original size
realloc( array, count / 2 * sizeof( int ) );
// display array after cut in half
cout << "\n\nThe elements of the array after reallocation are:\n";

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

8
47
48
49
50
51
52

Appendix E C Legacy Code Topics

for ( int k = 0; k < count / 2; k++ )


cout << setw( 3 ) << array[ k ];
cout << '\n';
return 0;
} // end main

This program dynamically allocates an array of integers.


Enter the number of elements in the array: 5
Enter an integer: 1
Enter an integer: 2
Enter an integer: 3
Enter an integer: 4
Enter an integer: 5
The elements of the array are:
1 2 3 4 5
The elements of the array after reallocation are:
1 2

E.7
Write a program that takes two file names as command-line arguments, reads the characters
from the first file one at a time and writes the characters in reverse order to the second file.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

// Exercise E.7 Solution: exE_07.cpp


#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::ios;
using std::cerr;
using std::istream;
using std::ostream;
#include <fstream>
using std::ofstream;
using std::ifstream;
// function prototype
void reverseFile( istream&, ostream& );
int main( int argc, char *argv[] )
{
// create input and output streams and open files
ifstream inFile( argv[ 1 ], ios::in );
ofstream outFile( argv[ 2 ], ios::out );
// tell user if program name and arguments opened improperly
if ( argc != 3 )
cout << "Usage: exE_07 infile outfile\n";
else

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

// reverse input file if both files opened successfully


if ( inFile )
if ( outFile )
reverseFile( inFile, outFile );
else // tell user output file could not be opened
cerr << "File \"" << argv[ 2 ] << "\" could not be opened\n";
else // tell user if input file could not be opened
cerr << "File \"" << argv[ 1 ] << "\" could not be opened\n";
return 0;
} // end main
// function that writes characters in reverse order
void reverseFile( istream &in, ostream &out )
{
int c;
// recursively call reverseFile until end-of-file reached
if ( ( c = in.get() ) != EOF )
reverseFile( in, out );
else
return; // do not write EOF character
// output characters in reverse order
out.put( static_cast< char > ( c ) );
} // end function reverseFile

C:\>exE_07.exe test.txt copy.txt

Contents of text.txt:
Programming in C++ is fun.

Contents of copy.txt:
.nuf si ++C ni gnimmargorP

E.8
Write a program that uses goto statements to simulate a nested looping structure that prints
a square of asterisks as shown in Fig. E.10. The program should use only the following three output
statements:

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

10

Appendix E C Legacy Code Topics


cout << '*';
cout << ' ';
cout << endl;

*****
*
*
*
*
*
*
*****

Fig. E.10 | Example for Exercise E.8.


ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

// Exercise E.8 Solution: exE_08.cpp


#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main()
{
int size; // length of square side
int row = 0; // number of rows
int col; // number of columns
// obtain length of side of square from user
cout << "Enter the side length of the square: ";
cin >> size;
start: // label
row++;
cout << endl;
// if all rows have been made end program
if ( row > size )
goto end;
col = 1; // set column variable to first character of line
innerLoop: // label
// if all columns have been displayed return to top of loop
if ( col > size )
goto start;
// display stars and spaces in appropriate positions
cout << ( row == 1 || row == size || col == 1 ||
col == size ? '*' : ' ' );
col++; // increment column
goto innerLoop; // continue displaying columns
end: // label

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
39
40

11

return 0;
} // end main

Enter the side length of the square: 7


*******
*
*
*
*
*
*
*
*
*
*
*******

E.9

Provide the definition for union Data containing


and double double1.

long1, float float1

char charcter1, short short1, long

ANS: union Data


{
char character1;
short short1;
long long1;
float float1;
double double1;
};

E.10

Create union Integer with members char charcter1, short short1, int integer1 and long
Write a program that inputs values of type char, short, int and long and stores the values
in union variables of type union Integer. Each union variable should be printed as a char, a short,
an int and a long. Do the values always print correctly?
long1.

ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

// Exercise E.10 Solution: exE_10.cpp


#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::ios;
union Integer
{
// member variables of Integer union
char c;
short s;
int i;
long l;
}; // end union Integer
// function prototype
void printUnion( Integer );
int main()
{

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

12
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

Appendix E C Legacy Code Topics

Integer value; // object of type Integer union


// ask user for and store character value
cout << "Enter a character: ";
value.c = static_cast< char >( cin.get() );
printUnion( value ); // print data members of Integer value
// ask user for and store short value
cout << "Enter a short: ";
cin >> value.s;
printUnion( value ); // print data members of Integer value
// ask user for and store int value
cout << "Enter an int: ";
cin >> value.i;
printUnion( value ); // print data members of Integer value
// ask user for and store long value
cout << "Enter a long: ";
cin >> value.l;
printUnion( value ); // print data members of Integer value
return 0;
} // end main
// function that prints member variables of Integer union
void printUnion( Integer x )
{
// display member variables
cout << "Current values in union Integer are:\n"
<< "char c = " << x.c
<< "\nshort s = " << x.s
<< "\nint i
= " << x.i
<< "\nlong l = " << x.l << "\n\n";
} // end function printUnion

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises

Enter a
Current
char c
short s
int i
long l

character: w
values in union Integer are:
= w
= -13193
= -858993545
= -858993545

Enter a
Current
char c
short s
int i
long l

short: 5
values in union Integer are:
= ?
= 5
= -859045883
= -859045883

13

Enter an int: 9999


Current values in union Integer are:
char c =
short s = 9999
int i
= 9999
long l = 9999
Enter a
Current
char c
short s
int i
long l

long: 1000000
values in union Integer are:
= @
= 16960
= 1000000
= 1000000

E.11

Create union FloatingPoint with members float float1, double double1 and long double
Write a program that inputs values of type float, double and long double and stores
the values in union variables of type union FloatingPoint. Each union variable should be printed as
a float, a double and a long double. Do the values always print correctly?

longDouble.

ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

// Exercise E.11 Solution: exE_11.cpp


#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::ios;
union FloatingPoint
{
// data members of FloatingPoint union
float f;
double d;
long double l;
}; // end union FloatingPoint
// function prototype
void printUnion( FloatingPoint );
int main()

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

14
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

Appendix E C Legacy Code Topics

FloatingPoint value; // object of type FloatingPoint union


// ask user for and store float value
cout << "Enter a float: ";
cin >> value.f;
printUnion( value ); // display data members of FloatingPoint value
// ask user for and store double value
cout << "Enter a double: ";
cin >> value.d;
printUnion( value ); // display data members of FloatingPoint value

// ask user for and store long double value


cout << "Enter a long double: ";
cin >> value.l;
printUnion( value ); // display data members of FloatingPoint value
return 0;
} // end main
// function that prints data members of a FloatingPoint union
void printUnion( FloatingPoint x )
{
// display data members of FloatingPoint union
cout << "Current values in union Integer are:\n"
<< "float f = " << x.f
<< "\ndouble d = " << x.d
<< "\nlong double l = " << x.l << "\n\n";
} // end function printUnion

Enter a float: 4.567


Current values in union Integer are:
float f = 4.567
double d = -9.25596e+061
long double l = -9.25596e+061
Enter a double: 9998888.765
Current values in union Integer are:
float f = 3.24255e-024
double d = 9.99889e+006
long double l = 9.99889e+006
Enter a long double: 5e306
Current values in union Integer are:
float f = 0.0210515
double d = 5e+306
long double l = 5e+306

E.12

Given the union


union A
{
double y;
char *zPtr;
};

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
which of the following are correct statements for initializing the union?

a)

A p = b;

// b is of type A

b)

A q = x;

// x is a double

c)

A r = 3.14159;

d)

A s = { 79.63 };

e)

A t = { "Hi There!" };

f)

A u = { 3.14159, "Pi" };

g)

A v = { y = 7.843, zPtr = &x };

ANS: Correct

ANS: Incorrect
ANS: Incorrect
ANS: Correct

ANS: Incorrect

ANS: Incorrect

ANS: Incorrect

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

15