#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream fin ("data1.txt");
int ID;
string name;
int test1, test2, test3;
char answer;
cin >> answer;
while (answer = 'Y')
{
fin >> ID;
getline(fin, name);
cout << name << endl;
fin >> test1, test2, test3;
cout << ID << endl;
cout << test1 << "\t" << test2 << "\t" << test3 << "\t";
cin >> answer;
}
}
http://postimg.org/image/fjknavue9/ (Image showing the error)
It showing this error.
For some reason it is just reading the first ID. And then garbage.
This is the TXT file
211692
Ahmed, Marco
66 88 99
240885
ATamimi, Trevone
30 60 90
281393
Choudhury, Jacob
45 55 65
272760
De la Cruz, Edward
79 89 49
199593
Edwards, Faraj
90 56 96
256109
Edwards, Bill
93 94 95
246779
Gallimore, Christian
22 88 66
270081
Lopez, Luis
100 100 100
114757
Mora, Sam
63 78 88
270079
Moses, Samuel
48 95 99
193280
Perez, Albert
97 57 0
252830
Rivas, Jonathan
44 56 76
252830
Robinson, Albert
85 87 89
276895
Miranda, Michael
82 72 62
280515
Robinson, Iris
64 78 91
Program wwill only read the first id, but nothing else, yet it will display whats given, if not garbage. With knowing the solution or understanding, what is going wrong, it can help me in another program that deals with the same logic.
As #Akshat Mahajan mentioned two problems in your code, I fixed and tested them.
One more thing is needed. You should add a line fin.ignore() to ignore the the new line after taking an integer from file.
Here is the working code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream fin ("data1.txt");
int ID;
string name;
int test1, test2, test3;
char answer;
cin >> answer;
while (answer == 'Y')
{
fin >> ID;
fin.ignore();
getline(fin, name);
cout << name << endl;
fin >> test1>> test2>> test3;
cout << ID << endl;
cout << test1 << "\t" << test2 << "\t" << test3 << "\t";
cin >> answer;
}
}
However, you have done some bad practice in your code. Instead of using answer == 'Y' as the condition of while, try something like fin>>ID.
If you choose to use getline for everything, you can change your code a little bit as below.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
ifstream fin ("data1.txt");
int ID;
string name, line;
int test1, test2, test3;
char answer;
cin >> answer;
while (answer == 'Y')
{
getline (fin, line);
ID = stoi(line);
getline(fin, name);
cout << name << endl;
getline(fin, line);
stringstream ss(line);
ss >> test1 >> test2 >> test3;
cout << ID << endl;
cout << test1 << "\t" << test2 << "\t" << test3 << "\t";
cin >> answer;
}
}
Related
I'm copying a part of my code that tries to save data from a text that is presented line per line. a, b, e, f are strings while the other variables are ints. The problem is that in e it saves nothing and in f saves the part corresponding to e. After this I try to read more data but always saves nothing in e. Please help
.
strong text
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
ifstream archivote;
archivote.open(vuelos.txt);
string line,a,b,e,f;
int ca,cb,cc,cd,ce,da,db,dc,dd,de,q;
while(getline(archivote, line)){
getline(archivote,a);
getline(archivote,b);
archivote >> ca;
archivote >> cb;
archivote >> cc;
archivote >> cd;
archivote >> ce;
archivote >> da;
archivote >> db;
archivote >> dc;
archivote >> dd;
archivote >> de;
getline(archivote,e);
getline(archivote,f);
cout << a << '\n' <<b << '\n'<< ca << '\n'<< cb
<< '\n'<< cc << '\n'<< cd << '\n'<< ce << '\n'
<< da << '\n'<< db << '\n'<< dc << '\n'<< dd <<
'\n' << de << '\n'<< e << '\n'<< f;
return 0;
}
}
And the text
Mexico
Puebla
12
12
2000
12
13
12
12
2000
12
22
AeroMexico
1234
Buenos Aires
Panama
02
12
2000
03
12
02
12
2000
05
23
Viva Aerobus
1592
This is my text file:
12345 shoe 5 0
34534 foot 72 1
34562 race 10 0
34672 chicken 24 150
88 pop 65 0
I need to take this file and go row by row, assign the first number as an identifier itemNum, second word as itemName, third number as itemPrice, and last number as itemAdjusmentValue. I will need to perform arithmetic with the last two numbers itemPrice and itemAdjusmentValue.
Code so far:
using namespace std;
// making a struct to store each value of the cuadre
struct Cuadre
{
int itemNum;
string itemName;
int itemPrice;
int itemAdjusment;
};
int main (){
ifstream infile("sheet_1.txt");
string checkLine;
if (infile.is_open()){
while ( infile.good()){
getline (infile, checkLine);
cout << checkLine << endl;
}
}
else
cout << "error with name of file" << endl;
vector<Cuadre> procedures;
Cuadre line;
while(Cuadre >> line.itemNum >> line.itemName >> line.itemPrice >> line.itemAdjusment){
procedures.push_back(line);
}
This code generates an error on the last while statement
expected primary-expression before '>>' token
I cant really find a specific tutorial on how to do this, and i've looked a good amount.
From the code you posted, (with reference to the >> istream operators) it looks like you want to stream the contents of the string data read from your file into the members of a struct.
It is not possible to stream directly from a std::string (eg: checkLine >> x >> y >> z), as string does not provide a streaming interface.
In order to do that you need to use a stream, such as std::stringstream.
You could populate a with your string checkLine, and then stream from that into your data members
std::stringstream ss(checkLine);
ss >> line.itemNum >> line.itemName >> line.itemPrice >> line.itemAdjusment;
Example code:
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
// making a struct to store each value of the cuadre
struct Cuadre
{
int itemNum;
string itemName;
int itemPrice;
int itemAdjusment;
};
int main (){
ifstream infile("sheet_1.txt");
string checkLine;
vector<Cuadre> procedures;
if (infile.is_open()){
while ( infile.good()){
getline (infile, checkLine);
cout << checkLine << endl;
Cuadre line;
std::stringstream ss(checkLine);
ss >> line.itemNum >> line.itemName >> line.itemPrice >> line.itemAdjusment;
procedures.push_back(line);
}
}
else
cout << "error with name of file" << endl;
return 0;
}
You need to push into the vector inside the loop that reads from the file. And you should be getting the fields from checkLine -- Cuadre is a type name, not a variable you can read from. But to do that you need to create a stringstream.
int main (){
ifstream infile("sheet_1.txt");
string checkLine;
vector<Cuadre> procedures;
if (infile.is_open()){
while (getline (infile, checkLine)){
Cuadre line;
cout << checkLine << endl;
stringstream linestream(checkline);
if (linestream >> line.itemNum >> line.itemName >> line.itemPrice >> line.itemAdjusment) {
procedures.push_back(line);
} else {
cout << "incorrect line" << endl;
break;
}
}
}
else {
cout << "error with name of file" << endl;
}
}
while (infile.good()) is also not correct, it's essentially the same as while (!infile.eof()). See Why is iostream::eof inside a loop condition considered wrong?
You can try reading directly into struct as well:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
struct Cuadre
{
int itemNum;
std::string itemName;
int itemPrice;
int itemAdjusment;
};
int main()
{
std::vector<Cuadre> procedures;
std::ifstream infile("sheet_1.txt");
while (infile)
{
Cuadre line;
if (infile >> line.itemNum >> line.itemName >> line.itemPrice >> line.itemAdjusment)
procedures.push_back(line);
else
break;
}
if (!procedures.empty())
{
for (auto &p : procedures)
std::cout
<< "itemNum: " << p.itemNum << "\t"
<< "itemName: " << p.itemName << "\t"
<< "itemPrice: " << p.itemPrice << "\t"
<< "itemAdjusment: " << p.itemAdjusment
<< std::endl;
}
else
std::cout << "error with file or data" << std::endl;
return 0;
}
Prints:
itemNum: 12345 itemName: shoe itemPrice: 5 itemAdjusment: 0
itemNum: 34534 itemName: foot itemPrice: 72 itemAdjusment: 1
itemNum: 34562 itemName: race itemPrice: 10 itemAdjusment: 0
itemNum: 34672 itemName: chicken itemPrice: 24 itemAdjusment: 150
itemNum: 88 itemName: pop itemPrice: 65 itemAdjusment: 0
If you define an overload of >> for your type Cuadre, you can read directly from the file into Cuadre objects.
std::istream& operator>>(std::istream& is, Cuadre & cuadre)
{
std::string s;
getline(is, s);
std::cout << s;
std::stringstream ss(s);
ss >> cuadre.itemNum >> cuadre.itemName >> cuadre.itemPrice >> cuadre.itemAdjusment;
return is;
// or without logging
return is >> cuadre.itemNum >> cuadre.itemName >> cuadre.itemPrice >> cuadre.itemAdjusment;
}
int main (){
ifstream infile("sheet_1.txt");
vector<Cuadre> procedures;
for (Cuadre line; infile >> line;) {
procedures.push_back(line);
}
// or with #include <algorithm>
std::copy(std::istream_iterator<Cuadre>{ infile }, {}, std::back_inserter(procedures));
}
I'm a very novice programmer, and I'm trying to make a program that reads a txt file containing the names of 5 students (first names only) as well as four exam scores for each student. I'm trying to read the names into an array called students, then read the scores into 4 separate arrays named test1, test2, test3, test4, then display it from the monitor. The file looks like this:
Steve 78 65 82 73
Shawn 87 90 79 82
Annie 92 90 89 96
Carol 72 65 65 60
Kathy 34 50 45 20
I'm having a very hard time with breaking up the arrays and organizing them. Can someone help me? Please keep in mind I'm very novice, so I don't know a large amount about programming.
This is my code thus far:
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <ctime>
#define over2 "\t\t"
#define over3 "\t\t\t"
#define over4 "\t\t\t\t"
#define down5 "\n\n\n\n\n"
using namespace std;
int main(int argc, char *argv[])
{
ifstream inputFile;
//Constant for max string size
const int SIZE = 5;
//Constant for the scores
string names[SIZE], fileName, line, test1[SIZE], test2[SIZE], test3[SIZE], test4[SIZE];
//input section, user enters their file name
cout << down5 << down5 << over2 << "Please enter your file name: ";
cin >> fileName;
system("CLS");
//open the file containing the responses
inputFile.open(fileName.c_str());
cout << endl;
//kicks you out if file isn't found
if (inputFile)
{
for(int i = 0; i < SIZE; i++)
{
getline(inputFile, line);
names[i] = line;
getline(inputFile, line);
test1[i] = line;
getline(inputFile, line);
test2[i] = line;
getline(inputFile, line);
test3[i] = line;
getline(inputFile, line);
test4[i] = line;
}
inputFile.close();
}
cout << down5 << over3 << "Student\tTest1\tTest2\tTest3\tTest4\n";
cout << over3 << "-------\t-----\t-----\t-----\t-----\n";
for(int i = 0; i < SIZE; i++)
{
cout << over3 << names[i] << endl;
cout << over3 << test1[i] << endl;
cout << over3 << test2[i] << endl;
cout << over3 << test3[i] << endl;
cout << over3 << test4[i] << endl;
}
return 0;
}
Let's look at the structure of the file you're trying to read:
Steve 78 65 82 73
Shawn 87 90 79 82
Annie 92 90 89 96
Carol 72 65 65 60
Kathy 34 50 45 20
The format of the data can be described as follows:
Each line represents a single "record".
Each "record" contains multiple columns.
Columns are separated by whitespace.
You're currently using getline() for every column:
for(int i = 0; i < SIZE; i++)
{
getline(inputFile, line);
names[i] = line;
getline(inputFile, line);
test1[i] = line;
getline(inputFile, line);
test2[i] = line;
getline(inputFile, line);
test3[i] = line;
getline(inputFile, line);
test4[i] = line;
}
...whereas you actually want to read in a single line for each record and split it up:
for (int i = 0; i < SIZE; i++)
{
string line;
size_t start = 0;
// For each line, attempt to read 5 columns:
getline(inputFile, line);
names[i] = get_column(line, start);
test1[i] = get_column(line, start);
test2[i] = get_column(line, start);
test3[i] = get_column(line, start);
test4[i] = get_column(line, start);
}
Here's a modified version of your original code, which splits up each line as described above:
#include <cctype>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
static string get_column(string line, size_t &pos)
{
size_t len = 0;
// Skip any leading whitespace characters.
while (isspace(line.c_str()[pos])) { ++pos; }
// Count the number of non-whitespace characters that follow.
while (!isspace(line.c_str()[pos+len]) && line.c_str()[pos+len]) { ++len; }
// Extract those characters as a new string.
string result = line.substr(pos, len);
// Update the "start" position (for the next time this function is called).
pos += len;
// Return the string.
return result;
}
int main()
{
const int SIZE = 5;
string names[SIZE], test1[SIZE], test2[SIZE], test3[SIZE], test4[SIZE];
// Ask the user to enter a file name.
cout << "Please enter your file name: ";
string fileName;
cin >> fileName;
// Open the file and read the data.
ifstream inputFile(fileName.c_str());
if (!inputFile.is_open()) { return 0; }
for (int i = 0; i < SIZE; i++)
{
string line;
size_t start = 0;
// For each line, attempt to read 5 columns:
getline(inputFile, line);
names[i] = get_column(line, start);
test1[i] = get_column(line, start);
test2[i] = get_column(line, start);
test3[i] = get_column(line, start);
test4[i] = get_column(line, start);
}
inputFile.close();
// Display the data.
cout << "Student\tTest1\tTest2\tTest3\tTest4" << endl;
cout << "-------\t-----\t-----\t-----\t-----" << endl;
for(int i = 0; i < SIZE; i++)
{
cout << names[i] << "\t";
cout << test1[i] << "\t";
cout << test2[i] << "\t";
cout << test3[i] << "\t";
cout << test4[i] << endl;
}
}
Running the program produces the following output:
Please enter your file name: textfile.txt
Student Test1 Test2 Test3 Test4
------- ----- ----- ----- -----
Steve 78 65 82 73
Shawn 87 90 79 82
Annie 92 90 89 96
Carol 72 65 65 60
Kathy 34 50 45 20
Note that the get_column() function handles multiple spaces or too-short lines, so that this file:
Steve 78 65 82 73
Shawn 87 90
Annie 92 90 89 96
Carol 72
Kathy 34 50 45 20
...produces the following output:
Please enter your file name: textfile.txt
Student Test1 Test2 Test3 Test4
------- ----- ----- ----- -----
Steve 78 65 82 73
Shawn 87 90
Annie 92 90 89 96
Carol 72
Kathy 34 50 45 20
The previous answer is overthinking the problem.
You can use your input file stream to retrieve 'formatted input' (that is, input you know to be in a format such as 'string' then 'int', 'int', 'int', 'int') with the >> operator.
string name;
int score[4];
ifstream mf;
mf.open("score.txt");
// Get name string.
mf >> name;
// Get four score values into an array.
mf >> score[0] >> score[1] >> score[2] >> score[3];
And then:
cout << name;
cout << score[0];
cout << score[1];
cout << score[2];
cout << score[3];
I've never posted here before but I'm really stuck so I thought i'd give it a try. I've been working on this code for a while, The aim is to input a few students with their marks and to output them into tables with averages and totals. I was given a file like this:
15
Albert Einstein 52 67 63
Steve Abrew 90 86 90 93
David Nagasake 100 85 93 89
Mike Black 81 87 81 85
Andrew Van Den 90 82 95 87
Joanne Dong Nguyen 84 80 95 91
Chris Walljasper 86 100 96 89
Fred Albert 70 68
Dennis Dudley 74 79 77 81
Leo Rice 95
Fred Flintstone 73 81 78 74
Frances Dupre 82 76 79
Dave Light 89 76 91 83
Hua Tran Du 91 81 87 94
Sarah Trapp 83 98
my problem is that when I am inputting the names the program crashes after Fred Flinstone, I know its not a problem with the formatting of the next name (Frances Dupre) because when i moved him up the list it read it fine.
I have located where the program is crashing with 'cerr' outputting at different stages of the read process and it crashes when it is trying to read in Frances's marks.
a1main.cpp
#include <iostream>
#include "student.h"
using namespace std;
int main()
{
int numStds;
cin >> numStds;
cerr << endl << "Num Stds: " << numStds << endl;
Student std[numStds+1];
for(int i = 0; i <= numStds; i++)
{
std[i].readData();
std[i].printStudent();
}
// delete [] std;
return 0;
}
student.h
#include <iostream>
using namespace std;
class Student {
private:
char* name;
int mark[4];
int num;
public:
Student();
~Student();
void readData();
void printStudent();
float getTotal();
float getAverage();
};
student.cpp
#include <iostream>
#include <cstring>
#include <cctype>
#include "student.h"
using namespace std;
Student::Student()
{
name = new char;
mark[0] = 0;
mark[1] = 0;
mark[2] = 0;
mark[3] = 0;
num = 0;
}
Student::~Student()
{
// Doesn't work?
// delete name;
}
void Student::readData()
{
int l = 0;
// Reading the Name
cin >> name; // Read in the first name
l = strlen(name); // get the strlength
name[l] = ' '; // Putting a space between the first and last name
cin >> &name[l+1]; // Read in the last name
cerr << endl << "I have read the name!" << endl;
// Checking if there is a third name
if(cin.peek() == ' ')
cin >> ws; // checking and navigating past the whitespace
char next = cin.peek();
if( isalpha(next) ) // Checking whether the next cin is a char
{
l = 0;
l = strlen(name);
name[l] = ' ';
cin >> &name[l+1];
}
cerr << "I've checked for a third name!" << endl;
// Reading in the marks
for(int i = 0; i < 4; i++)
{
// Checks if the next cin is a newline
if (cin.peek() == '\n')
break;
cin >> mark[i];
}
cerr << "I've read in the marks!" << endl;
//cerr << endl << "I have read " << name << "'s marks!" << endl << endl;
for(int m = 0; m < 4; m++)
{
if(mark[m] != 0)
{
num++;
}
}
cerr << "I've incremented num!" << endl << endl;
}
// Function for error checking
void Student::printStudent()
{
cout << endl << "Student Name: " << name << endl;
cout << "Mark 1: " << mark[0] << endl;
cout << "Mark 2: " << mark[1] << endl;
cout << "Mark 3: " << mark[2] << endl;
cout << "Mark 4: " << mark[3] << endl;
cout << "num marks: " << num << endl << endl;
}
float Student::getTotal()
{}
float Student::getAverage()
{}
Can anyone see what i'm doing wrong? thanks :)
You're never allocating memory to store the student names.
In your Student constructor, add this code:
name = new char[100]; // allows names up to 100 characters long
and uncomment this line in the destructor:
delete[] name;
You could also make the code more sophisticated and robust by measuring the name length and allocating the correct size, or use std::string as suggested below.
Im trying to read a list like this one
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
and store each value into a a separate variable. The names are strings, and the other numbers are floats and an int. I can get the data from one line so far, but I dont know how to go onto the next line and do the same. Here is my code so far.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream employees;
string lastname, firstname, lastname1, firstname1, lastname2, firstname2;
float base, sales, base1, sales1, base2, sales2;
int years, years1, years2;
employees.open("employees.txt");
while (employees)
{
employees >> lastname >> firstname >> base >> sales >> years;
I want to keep it as simple as possible, I dont know user defined functions, arrays, or vectors at all yet. So is there a simple function that will just end the line at years; and go to the next line and carry on?
Thanks.
Use an array. Whenever you end up with "I want to add a number to this variable because I want more than one", if the number reaches more than 2, then you should really use an array (unless very special cases).
You may also want to use a struct to store your different values (firstname, lastname, base, sales and years) - that way, you only get a single array, rather than several different arrays.
Since this is C++, arrays means vector. In other words:
struct employee
{
string firstname, lastname;
float base, sales;
int years;
};
vector<employee> emp_table;
employee e;
while (employees >> e.firstname >> e.lastname >> e.base >> e.sales >> e.years)
{
emp_table.push_back(e);
}
Note I put the input of employees as the while-condition. This avoids an extra loop iteration and "pushing back" a second copy of the last entry when you have reached end of file.
There are many ways in C++ to accomplish what you are trying to do. One approach that allows for data validation is to use the std::getline function to read the file one line at a time and then use a std::stringstream to parse the data.. This allows you to validate the data and continue processing if the data on a line is malformed.
[As Mats noted you can use a data structure and std::vector to make storing and managing the data easier.]
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
struct employee
{
std::string firstname;
std::string lastname;
float base;
float sales;
int years;
};
int main()
{
std::ifstream employeeFile;
employeeFile.open("employees.txt");
std::string tmpLine;
std::vector<employee> employeeTable;
// read in an entire line at a time
while(std::getline(employeeFile, tmpLine))
{
// Place the input line into a stream that reads from
// a string instead of a file.
std::stringstream inputLine(tmpLine);
// Try parsing the data. The ! operator is used here to check
// for errors. Since we expect the data to be in a specific format
// we want to be able to handle situations where the input line
// may be malformed. For example, encountering a string where
// a number should be.
employee e;
if(!(inputLine >> e.firstname >> e.lastname >> e.base >> e.sales >> e.years))
{
// ... error parsing input. Report the error
// or handle it in some other way.
continue; // keep going!
}
// Add to the vector
employeeTable.push_back(e);
}
return 0;
}
You can use getline inside your loop to retrieve each line and then use it with a stringstream
Something like:
string line;
while(getline(employees,line))
{
//doSomething
}
If you can't use arrays to store them easily, you can put a counter to know at which line you're at, but this is very repetitive, and the number of lines in your file cannot vary:
string line;
for (int count = 1 ; count <= 3 ; count++)
{
getline(employees,line);
istringstream iss(line);
if (count == 1)
{
iss >> lastname >> firstname >> base >> sales >> years;
}
else if (count == 2)
{
iss >> lastname1 >> firstname1 >> base1 >> sales1 >> years1;
}
else if (count == 3)
{
iss >> lastname2 >> firstname2 >> base2 >> sales2 >> years2;
}
}
Opening and reading a file properly is harder than learning what an array is. If you don't use an array you have to use too many variables to hold all your data, and you have to repeatedly write the code to read from the file, rather than writing it once in a loop.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string firstNames[3];
string lastNames[3];
float heights[3];
float weights[3];
int ages[3];
ifstream infile("data.txt");
if(!infile)
{
cout << "Couldn't open file!" << endl;
return 1;
}
int count = 0;
while (infile >> firstNames[count]
>> lastNames[count]
>> heights[count]
>> weights[count]
>> ages[count] )
{
++count;
}
infile.close();
for (int i = 0; i<count; ++i) {
cout << firstNames[i] << " "
<< lastNames[i] << " "
<< heights[i] << " "
<< weights[i] << " "
<< ages[i] << " " << endl;
}
return 0;
}
--output:--
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
Compare to this disaster:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string firstName0,firstName1, firstName2;
string lastName0, lastName1, lastName2;
float height0, height1, height2;
float weight0, weight1, weight2;
int age0, age1, age2;
ifstream infile("data.txt");
if(!infile)
{
cout << "Couldn't open file!" << endl;
return 1;
}
infile >> firstName0 >> lastName0 >> height0 >> weight0 >> age0;
infile >> firstName1 >> lastName1 >> height1 >> weight1 >> age1;
infile >> firstName2 >> lastName2 >> height2 >> weight2 >> age2;
infile.close();
cout << firstName0 << " "
<< lastName0 << " "
<< height0 << " "
<< weight0 << " "
<< age0 << endl;
cout << firstName1 << " "
<< lastName1 << " "
<< height1 << " "
<< weight1 << " "
<< age1 << endl;
cout << firstName2 << " "
<< lastName2 << " "
<< height2 << " "
<< weight2 << " "
<< age2 << endl;
return 0;
}
--output:--
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
Look at all the code you have to repeat.
Note that when you use an array, the variable names become firstNames[0] (v. firstName0), lastNames[0] (v. lastName0), etc., and firstNames[1] (v. firstName1) and lastNames[1] (v. lastName0).