Chapter 14

RECORDS (C++ STRUCTS)

EXERCISE ANSWERS

Exam Preparation Exercises

1. Record (struct) A heterogeneous data structure in which the components are accessed by name, not by index

Member A component of a struct

Member selector The expression used to access a member of a struct variable; composed of the name of the struct variable and the member name, separated by a dot (period)

Hierarchical record A record that contains another record as a component

Data abstraction The separation of the logical properties of a data type from its

implementation details

4. All the components of an array must be of the same data type; the components of a record may be of different types. The components of an array are accessed by an index; the components of a record are accessed by a member name.

6. True

8. Item Value

today.month 1

today.day 1

today.year 1996

Item Value

aName The string " "

aFriend.firstName The string " "

aFriend.lastName The string " "

aFriend.birthDate.month 1

aFriend.birthDate.day 1

aFriend.birthDate.year 1996

self.firstName The string " "

self.lastName The string " "

self.birthDate.month 1

self.birthDate.day 1

self.birthDate.year 1996

9. struct RecType

{

int intMember1;

int intMember2;

Boolean boolMember;

};

10. if (currentDate.year != inventory[index].history.lastServiced.year)

11. #include <string.h> // For strcpy()

.

.

strcpy(person.name.first, "Clara");

strcpy(person.name.last, "Herrmann");

strcpy(person.place.city, "White Bluffs");

strcpy(person.place.state, "WA");

person.place.zipCode = 99352;

Programming Warm-Up Exercises

2. const int NUM_PARTS = 100;

struct PartType

{

int number;

float cost;

};

int main()

{

PartType partList[NUM_PARTS];

PartType tempPart;

int listLength = 0;

cin >> tempPart.number >> tempPart.cost;

while (cin)

{

// Call the Insert function from Chapter 12,

// using proper declarations

Insert(partList, listLength, tempPart);

cin >> tempPart.number >> tempPart.cost;

}

.

.

4. a. typedef char String20[21];

struct AptType

{

String20 landlord;

String20 address;

int bedrooms;

float price;

};

b. AptType available[200];

c. void GetRecord( /* out */ AptType& forLease )

{

cin.get(forLease.landlord, 21); // May contain embedded blanks

cin.get(forLease.address, 21);

cin >> forLease.bedrooms >> forLease.price;

}

5. a. aRef = aMap.chart;

b. guide[3] = aMap;

c. #include <string.h> // For strcpy()

.

.

strcpy(guide[9].mapCode, aCode);

d. if (aCode[0] == guide[1].mapCode[0])

{

cout << guide[1].mapCode << endl;

if (guide[1].style == FORMAL)

cout << "formal" << endl;

else

cout << "brief" << endl;

}

e. #include <string.h> // For strcmp()

.

.

cout << "The token members differ in the following "

<< "positions (if any):" << endl;

for (i = 0; i < 2000; i++)

if (strcmp(aMap.chart.token[i], aRef.token[i]) != 0)

cout << i << endl;

cout << "The symbol members differ in the following "

<< "positions (if any):" << endl;

for (i = 0; i < 20; i++)

if (strcmp(aMap.chart.symbol[i], aRef.symbol[i]) != 0)

cout << i << endl;

 

6. a. typedef char String10[11];

typedef char String30[31];

typedef char String100[101];

typedef char String300[301];

struct EntryType

{

String10 callNumber;

int numCopies;

String30 author;

String100 title;

String300 description;

};

b. 448 characters per book; 22,400,000 total characters

c. 1450

7. The input strings may contain embedded blanks, so we use the cin.get function for input.

void ReadBook( /* out */ EntryType& book )

{

cin.get(book.callNumber, 11);

cin >> book.numCopies;

cin.get(book.author, 31);

cin.get(book.title, 101);

cin.get(book.description, 301);

}

//************************************************

void WriteBook( /* in */ EntryType book )

{

cout << book.callNumber << ' ' << book.numCopies << ' '

<< book.author << ' ' << book.title << endl

<< book.description << endl;

}

8. typedef char String30[31];

struct DateType1

{

int month;

int year;

};

struct DateType2

{

int month;

int day;

int year;

};

struct AddressType

{

String30 street;

String30 city;

String30 state;

long zipCode;

};

struct SubscriberType

{

String30 firstName;

String30 lastName;

AddressType address;

DateType1 expireDate;

DateType2 dateSent;

int numNotices;

int numYears;

Boolean nameForSale;

};

9. typedef char String15[16];

enum ParityType {EVEN, ODD, ONE, ZERO, NONE};

enum EchoplexType {HALF, FULL};

struct TerminalType

{

String15 brandAndModel;

int dataRate;

ParityType parity;

EchoplexType echoplex;

int dataBits;

int stopBits;

};

11. Given the declaration

struct String

{

char str[21]; // A null-terminated string

int length; // Length excluding '\0'

};

here is one version of the concatenation function:

#include <string.h> // For strcpy()

.

.

void Concat( /* in */ String str1,

/* in */ String str2,

/* out */ String& str3 )

// Precondition:

// str1 and str2 are assigned

// && str1.length + str2.length <= 20

// Postcondition:

// str3.str is the string obtained by concatenating str2.str

// to the end of str1.str

// && str3.length == str1.length + str2.length

{

int i; // Index into str2.str array

strcpy(str3.str, str1.str);

for (i = 0; i <= str2.length; i++) // Use "<=" to be sure we

// copy the final '\0'

// Invariant (prior to test):

// str2.str[0..i-1] have been copied into

// str3.str[str1.length..str1.length+i-1]

// && 0 <= i <= str2.length + 1

str3.str[i+str1.length] = str2.str[i];

str3.length = str1.length + str2.length;

}

Here is another version of the function body, simplified by using the strcat library function (Appendix C):

{

strcpy(str3.str, str1.str);

strcat(str3.str, str2.str);

str3.length = str1.length + str2.length;

}

12. typedef char String30[31];

struct Inventory

{

String30 partNumber; // May contain alphanumeric chars

String30 partName;

float cost;

int quantity;

};

void ReadPart( /* out */ Inventory& part )

{

cin.get(part.partNumber, 31);

cin.get(part.partName, 31);

cin >> part.cost >> part.quantity;

}

13. void GetRecords( /* inout */ ifstream& inFile, // Input file

/* out */ PersonRec list[] ) // List receiving

// input records

{

int index = 0; // Array index

Boolean moreData; // True until sentinel is reached

do

{

inFile >> list[index].lastName;

moreData = (strcmp(list[index].lastName, SENTINEL) != 0);

if (moreData)

inFile >> list[index].firstName

>> list[index].phone.areaCode

>> list[index].phone.phoneNumber;

index++;

} while (moreData);

}

 

14. In the main function, add the following declarations:

int length1; // Length of firstList

int length2; // Length of secondList

int lengthTemp; // Length of tempList

int lengthMaster; // Length of masterList

In the main function's sequence of function calls, include additional parameters that indicate the lengths of the various lists:

GetRecords(file1, firstList, length1);

GetRecords(file2, secondList, length2);

Merge(firstList, secondList, tempList, length1, length2, lengthTemp);

GetRecords(file3, firstList, length1);

Merge(firstList, tempList, masterList, length1, lengthTemp, lengthMaster);

Write(masterList, masterFile, lengthMaster);

Change the GetRecords, Merge, Append, and Write functions as follows. (To save space, we have omitted the function pre- and postconditions and the loop invariants.)

void GetRecords( /* inout */ ifstream& inFile, // Input file

/* out */ PersonRec list[], // List receiving

// input records

/* out */ int& length ) // Length of list

{

String15 tempName; // Temporary input name

length = 0;

inFile >> tempName;

while (strcmp(tempName, SENTINEL) != 0)

{

strcpy(list[length].lastName, tempName);

inFile >> list[length].firstName

>> list[length].phone.areaCode

>> list[length].phone.phoneNumber;

length++;

inFile >> tempName;

}

}

 

//******************************************************************

void Merge(

/* in */ const PersonRec list1[], // List to merge

/* in */ const PersonRec list2[], // List to merge

/* out */ PersonRec mergedList[], // Resulting merged list

/* in */ int length1, // Length of list1

/* in */ int length2, // Length of list2

/* out */ int& length3 ) // Length of mergedlist

{

int index1 = 0; // Index variable for list1

int index2 = 0; // Index variable for list2

int strRelation; // Result of comparing two last names

length3 = 0;

while (index1 < length1 && index2 < length2)

{

strRelation = strcmp(list1[index1].lastName,

list2[index2].lastName);

if (strRelation < 0)

{

// Assert: Last name in 1st list is less than in 2nd

mergedList[length3] = list1[index1];

index1++;

}

else if (strRelation > 0)

{

// Assert: Last name in 1st list is greater than in 2nd

mergedList[length3] = list2[index2];

index2++;

}

else

{

// Assert: Last names are the same in both lists

mergedList[length3] = list1[index1];

index1++;

index2++;

}

length3++;

}

Append(list1, list2, mergedList, index1, index2, length3,

length1, length2);

}

//******************************************************************

void Append(

/* in */ const PersonRec list1[], // List being merged

/* in */ const PersonRec list2[], // List being merged

/* inout */ PersonRec mergedList[], // Resulting list

/* inout */ int& index1, // Index for list1

/* inout */ int& index2, // Index for list2

/* inout */ int& length3, // Length of mergedList

/* in */ int length1, // Length of list1

/* in */ int length2 ) // Length of list2

{

// Append rest of list1, if more exists

while (index1 < length1)

{

mergedList[length3] = list1[index1];

index1++;

length3++;

}

// Append rest of list2, if more exists

while (index2 < length2)

{

mergedList[length3] = list2[index2];

index2++;

length3++;

}

}

//******************************************************************

void Write( /* in */ const PersonRec masterList[], // Merged list

/* inout */ ofstream& masterFile, // Output file

/* in */ int length ) // Length of

// masterList

{

int index; // Loop control and index variable

for (index = 0; index < length; index++)

masterFile << masterList[index].lastName << ' '

<< masterList[index].firstName << ' '

<< masterList[index].phone.areaCode << ' '

<< masterList[index].phone.phoneNumber << endl;

// Write sentinel record

masterFile << "ZZZZZZZZZZZZZZZ A 111 111-1111" << endl;

}

 

ANSWERS TO QUESTIONS

True/False

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

 

Multiple Choice

  1. c 20. b 23. a 26. a 29. e
  2. d 21. a 24. b 27. e 30. c
  3. d 22. d 25. d 28. d 31. d

Fill-In

32. record (struct)

33. member selector

34. hierarchical

35. member

36. heterogeneous

37. union

38. data abstraction

39. inventory[9]

40. inventory[0].price

41. inventory[0].description

42. inventory[0].description[0]

43. cout << aNovel.author;

44. cout << flower[4].name;

45. cout << baby[0].lastName;

46. cout << baby[11].firstName[1];

47. cout << boss.employmentDate.year;

48 cout << oneBoard.dimensions.width;