Ok, thanks to zen and everyone else helping with this code. I added zen's code to read the file, and it works ok. Reading the file isn't actually part of the assignment, but I use it to check that it's being done correctly. I've been puzzling over this for a few days, don't know why it's so hard. I can finish the assignment, but want to know why it's doing what it's doing.
Even when opening the file in binary, I can read it in Notepad, w/o using memset.
Anyway, in Notepad the file still contains the remnant "gned" in the lastName field (for a 5 character name). Why doesn't the personOut.write line with blank overwrite that?
Tha age variable is a char[4] in the assignment, probably because the fields need to be a set length for random access. Using an int instead gives some binary type character when displaying it.
Thanks again.
ofstream personOut("nameAge.dat", ios::binary);
	if (!personOut) {cout << "Error!";}
	person id = {"unassigned", "", 0};
	person blank = {"             ", "", 0};
	for (int i = 0; i < 100; i++)
		personOut.write((char *)&id, sizeof(person));

	// 14.11.b	Enter records sequentially
	int numOfRec;
	cout << "\nEnter number of records to enter: ";
	cin >> numOfRec;
	for (int j = 0; j < numOfRec; j++)
		personOut.seekp(j * sizeof(person));
		personOut.write((char *)&blank, sizeof(person));
		cout << "\nEnter last name, first name and age: ";
		cin >> id.lastName >> id.firstName >> id.age;
		personOut.seekp(j * sizeof(person));
		personOut.write((char *)&id, sizeof(person));

    ifstream personIn("nameAge.dat", ios::binary);
    for(int k =0;k<numOfRec;k++)
		personIn.seekg(k * sizeof(person));
		personIn.read((char *)&id, sizeof(person));
        cout << id.lastName  <<  " "<< id.firstName << " "<< id.age << endl;