Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

// C++ // Here\'s my code as of now. //ArgumentManager.h #include <map> #include

ID: 3749495 • Letter: #

Question

// C++

// Here's my code as of now.

//ArgumentManager.h

#include <map>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;

class ArgumentManager {
private:
map m_argumentMap;
public:
ArgumentManager() { }
ArgumentManager(int argc, char *argv[], char delimiter=';');
ArgumentManager(string rawArguments, char delimiter=';');
void parse(int argc, char *argv[], char delimiter=';');
void parse(string rawArguments, char delimiter=';');
string get(string argumentName);
string toString();
friend ostream& operator << (ostream &out, ArgumentManager &am);
};

void ArgumentManager::parse(string rawArguments, char delimiter) {
stringstream currentArgumentName;
stringstream currentArgumentValue;
bool argumentNameFinished = false;
  
for (unsigned int i=0; i<=rawArguments.length(); i++) {
if (i == rawArguments.length() || rawArguments[i] == delimiter) {
if (currentArgumentName.str() != "") {
m_argumentMap[currentArgumentName.str()] = currentArgumentValue.str();
}
// reset
currentArgumentName.str("");
currentArgumentValue.str("");
argumentNameFinished = false;
}
else if (rawArguments[i] == '=') {
argumentNameFinished = true;
}
else {
if (argumentNameFinished) {
currentArgumentValue << rawArguments[i];
}
else {
// ignore any spaces in argument names.
if (rawArguments[i] == ' ')
continue;
currentArgumentName << rawArguments[i];
}
}
}
}

void ArgumentManager::parse(int argc, char *argv[], char delimiter) {
if (argc > 1) {
for (int i=1; i parse(argv[i], delimiter);
}
}
}

ArgumentManager::ArgumentManager(int argc, char *argv[], char delimiter) {
parse(argc, argv, delimiter);
}

ArgumentManager::ArgumentManager(string rawArguments, char delimiter) {
parse(rawArguments, delimiter);
}

string ArgumentManager::get(string argumentName) {
map::iterator iter = m_argumentMap.find(argumentName);

//If the argument is not found, return a blank string.
if (iter == m_argumentMap.end()) {
return "";
}
else {
return iter->second;
}
}

string ArgumentManager::toString() {
stringstream ss;
for (map::iterator iter = m_argumentMap.begin(); iter != m_argumentMap.end(); iter++) {
ss << "Argument name: " << iter->first << endl;
ss << "Argument value: " << iter->second << endl;
}
return ss.str();
}

ostream& operator << (ostream &out, ArgumentManager &am) {
out << am.toString();
return out;
}

// sort.cpp

#include <cstdlib>

#include <string>

#include <vector>

#include <sstream>

#include <fstream>

#include <iostream>

#include <iomanip>

#include <sys/stat.h>

#include "ArgumentManager.h"

using namespace std;

typedef struct node_type {

long int id;

string fname;

string lname;

string s;

string dob;

string sort;

float gpa;

struct node_type *next;

}node;

void deleteRecord(node* &head, string id){

long myLong = std::stol(id);

node* prev = head; // empty header

node* current = head->next; // the first valid node

while(current != NULL) {

if(current->id == myLong) {

break;

}

else {

cout << "id " << current->id << " does not match " << myLong << ". ";

prev = current;

current = current->next; // go to next id

}

}

if(current == NULL) { // if we reached end of list or the list is empty

cout << "Can't remove id: no match found. ";

} else {

//cout << "Deleting: " << current << " ";

prev->next = current->next; // unlink the node you remove

delete current; // delete the node

}

}

void addRecord(node* &head, string line){

node *new_node = new node;

string fn, ln, dob;

string id;

string gpa;

stringstream ss;

int i = 0;

cout << line << endl;

string temp_line,first_word, second_word;

temp_line = line;

stringstream s(temp_line);

s >> first_word;

s >> second_word;

if (first_word == "delete"){

cout << "seen delete" <

deleteRecord(head, second_word);

}

else{

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while ( i < line.length() && line[i] != ',') {

id.push_back(line[i]);

i++;

}

i++;

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while (i < line.length() && line[i] != ',') {

fn.push_back(line[i]);

i++;

}

i++;

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while (i < line.length() && line[i] != ',') {

ln.push_back(line[i]);

i++;

}

i++;

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while (i < line.length() && line[i] != ',') {

dob.push_back(line[i]);

i++;

}

i++;

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while (i < line.length() && line[i] != '}') {

gpa.push_back(line[i]);

i++;

}

ss << id;

ss << " ";

ss << gpa;

new_node->dob = dob;

new_node->fname = fn;

new_node->lname = ln;

new_node->next = NULL;

ss >> new_node->id;

ss >> new_node->gpa;

ss.clear();

if (head == NULL) {

head = new_node;

head->next = NULL;

}

else

{

node *cur = head;

while (cur->next != NULL) {

cur = cur->next;

}

cur->next = new_node;

}

}

}

void swap(node *first, node *second) {

node *temp = new node;

temp->dob = first->dob;

temp->fname = first->fname;

temp->gpa = first->gpa;

temp->id = first->id;

temp->lname = first->lname;

first->dob = second->dob;

first->fname = second->fname;

first->lname = second->lname;

first->id = second->id;

first->gpa = second->gpa;

second->dob = temp->dob;

second->fname = temp->fname;

second->lname = temp->lname;

second->id = temp->id;

second->gpa = temp->gpa;

}

void sortByFirstName(node *head){

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL)

{

if (cur1->fname > cur2->fname)

{

swap(cur1, cur2);

}

else if (cur1->fname == cur2->fname)

{

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void sortByLastName(node *head){

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL)

{

if (cur1->lname > cur2->lname)

{

swap(cur1, cur2);

}

else if (cur1->lname == cur2->lname)

{

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void sortByGpa(node *head){

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL) {

if (cur1->gpa > cur2->gpa)

{

swap(cur1, cur2);

}

else if (cur1->gpa == cur2->gpa)

{

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void sortByDOB(node *head) {

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL)

{

if (cur1->dob > cur2->dob)

{

swap(cur1, cur2);

}

else if (cur1->dob == cur2->dob)

{

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void sortByID(node *head){

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL) {

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void write(string file, node *head) {

ofstream ofs;

ofs.open(file.c_str());

if (ofs.is_open())

{

node *cur = head;

node *cur1 = head;

cur1 = cur->next;

while (cur != NULL && cur1 != NULL)

{

if (cur1->id != cur->id && cur->gpa == 4 || cur->gpa == 3 || cur->gpa == 2 || cur->gpa == 1 || cur->gpa == 0)

{

ofs << "{id:" << cur->id << ",first:" << cur->fname << ",last:" << cur->lname;

ofs << ",DOB:" << cur->dob << ",GPA:" << cur->gpa << ".0}";

ofs << endl;

cur = cur->next;

cur1 = cur1->next;

}

else if (cur1->id != cur->id) //when ids are not the same. print.

{

ofs << "{id:" << cur->id << ",first:" << cur->fname << ",last:" << cur->lname;

ofs << ",DOB:" << cur->dob << ",GPA:" << cur->gpa << "}";

ofs << endl;

cur = cur->next;

cur1 = cur1->next;

}

else //else ignore line

{

cur = cur->next;

cur1 = cur1->next;

}

if (cur1 == NULL) //print last line

{

if (cur->gpa == 4 || cur->gpa == 3 || cur->gpa == 2 || cur->gpa == 1 || cur->gpa == 0)

{

ofs << "{id:" << cur->id << ",first:" << cur->fname << ",last:" << cur->lname;

ofs << ",DOB:" << cur->dob << ",GPA:" << cur->gpa << ".0}";

ofs << endl;

}

else

{

ofs << "{id:" << cur->id << ",first:" << cur->fname << ",last:" << cur->lname;

ofs << ",DOB:" << cur->dob << ",GPA:" << cur->gpa << "}";

ofs << endl;

}

}

}

}

}

int main(int argc, char* argv[]){

node *head = NULL;

ifstream ifs,ifsSort;

string input;

string line;

// You can add code here to split file name from the command line

// For now, using static file names for input, sort and output

ifs.open("input12.txt", ios::in);

if (ifs.is_open() == false)

{

cout << " File Opening Error - Input File";

exit(0);

}

while (!ifs.eof())

{

getline(ifs, line);

addRecord(head, line);

}

//code to sort

ifsSort.open("sort12.txt", ios::in);

if (ifsSort.is_open() == false)

{

cout << " File Opening Error - Sort File";

exit(0);

}

// To get last line from sort text file

// while (!ifsSort.eof())

// {

// cout << "line is " << line<< endl;

// getline(ifsSort, line);

// }

string lastline;

while (!ifsSort.fail()) {

getline(ifsSort, line );

if (!ifsSort.fail()) {

lastline = line;

}

}  

line = lastline;

cout << "last line is " << line<< endl;

int choice;

if (line == "id")

choice = 1;

else if (line == "first")

choice = 2;

else if (line == "last")

choice = 3;

else if (line == "DOB")

choice = 4;

else if (line == "GPA")

choice = 5;

//Note : In cpp switch can not take string as choice variable. we need to convert choice to integers first.

switch (choice) // run-time

{

case 1: // compile-time

sortByID(head);

break;

case 2: // compile-time

sortByFirstName(head);

break;

case 3: // compile-time

sortByLastName(head);

break;

case 4: // compile-time

sortByDOB(head);

break;

case 5: // compile-time

sortByGpa(head);

break;

default:

std::cout << "Invalid Sorting Criteria" << std::endl;

break;

};

input = "output12.txt";

write(input, head); //delete duplicates and output the list

//system("pause");

int x;

cin >> x;

}

// Input12.txt:

// {id:1234567,first:Mary,last:Green,DOB:1996-10-03,GPA:4.0}

// {id:1234568,first:Peter,last:White,DOB:1997-05-22,GPA:3.8}

// {id:1654238,first:Nick,last:Park,DOB:1995-08-18,GPA:4.0}

// {id:1234587,first:Katy,last:Green,DOB:1995-08-18,GPA:4.0}

// delete 1234568

// {id:1234570,first:Peter,last:White,DOB:1997-05-22,GPA:3.8}

// sort12.txt:

// id

// DOB

// output12.txt

// {id:1234587,first:Katy,last:Green,DOB:1995-08-18,GPA:4.0}

// {id:1654238,first:Nick,last:Park,DOB:1995-08-18,GPA:4.0}

// {id:1234567,first:Mary,last:Green,DOB:1996-10-03,GPA:4.0}

// {id:1234570,first:Peter,last:White,DOB:1997-05-22,GPA:3.8}

// Problem: I need help changing it from using static file names for input, sort, and output.

And instead split file name from the command line. so I could use ./sort “input=input12.txt;output=output12.txt;sort=sort12.txt”

Do not use hard coding. For example, file.open("1.txt");

// If needs to be more information, let me know in the comments.

Explanation / Answer

#include <map>

#include <string>

#include <iostream>

#include <sstream>

using namespace std;

class ArgumentManager {

private:

map<string,string> m_argumentMap;

public:

ArgumentManager() { }

ArgumentManager(int argc, char *argv[], char delimiter=';');

ArgumentManager(string rawArguments, char delimiter=';');

void parse(int argc, char *argv[], char delimiter=';');

void parse(string rawArguments, char delimiter=';');

string get(string argumentName);

string toString();

friend ostream& operator << (ostream &out, ArgumentManager &am);

};

void ArgumentManager::parse(string rawArguments, char delimiter) {

stringstream currentArgumentName;

stringstream currentArgumentValue;

bool argumentNameFinished = false;

  

for (unsigned int i=0; i<=rawArguments.length(); i++) {

if (i == rawArguments.length() || rawArguments[i] == delimiter) {

if (currentArgumentName.str() != "") {

m_argumentMap[currentArgumentName.str()] = currentArgumentValue.str();

}

// reset

currentArgumentName.str("");

currentArgumentValue.str("");

argumentNameFinished = false;

}

else if (rawArguments[i] == '=') {

argumentNameFinished = true;

}

else {

if (argumentNameFinished) {

currentArgumentValue << rawArguments[i];

}

else {

// ignore any spaces in argument names.

if (rawArguments[i] == ' ')

continue;

currentArgumentName << rawArguments[i];

}

}

}

}

void ArgumentManager::parse(int argc, char *argv[], char delimiter) {

if (argc > 1) {

for (int i=1; i < argc; i++)

parse(argv[i], delimiter);

}

}

ArgumentManager::ArgumentManager(int argc, char *argv[], char delimiter) {

parse(argc, argv, delimiter);

}

ArgumentManager::ArgumentManager(string rawArguments, char delimiter) {

parse(rawArguments, delimiter);

}

string ArgumentManager::get(string argumentName) {

map<string, string>::iterator iter = m_argumentMap.find(argumentName);

//If the argument is not found, return a blank string.

if (iter == m_argumentMap.end()) {

return "";

}

else {

return iter->second;

}

}

string ArgumentManager::toString() {

stringstream ss;

for (map<string, string>::iterator iter = m_argumentMap.begin(); iter != m_argumentMap.end(); iter++) {

ss << "Argument name: " << iter->first << endl;

ss << "Argument value: " << iter->second << endl;

}

return ss.str();

}

ostream& operator << (ostream &out, ArgumentManager &am) {

out << am.toString();

return out;

}

------------sort.cpp-------------

// sort.cpp

#include <cstdlib>

#include <string>

#include <vector>

#include <sstream>

#include <fstream>

#include <iostream>

#include <iomanip>

#include <sys/stat.h>

#include "ArgumentManager.h"

using namespace std;

typedef struct node_type {

long int id;

string fname;

string lname;

string s;

string dob;

string sort;

float gpa;

struct node_type *next;

}node;

void deleteRecord(node* &head, string id){

long myLong = std::stol(id);

node* prev = head; // empty header

node* current = head->next; // the first valid node

while(current != NULL) {

if(current->id == myLong) {

break;

}

else {

cout << "id " << current->id << " does not match " << myLong << ". ";

prev = current;

current = current->next; // go to next id

}

}

if(current == NULL) { // if we reached end of list or the list is empty

cout << "Can't remove id: no match found. ";

} else {

//cout << "Deleting: " << current << " ";

prev->next = current->next; // unlink the node you remove

delete current; // delete the node

}

}

void addRecord(node* &head, string line){

node *new_node = new node;

string fn, ln, dob;

string id;

string gpa;

stringstream ss;

int i = 0;

cout << line << endl;

string temp_line,first_word, second_word;

temp_line = line;

stringstream s(temp_line);

s >> first_word;

s >> second_word;

if (first_word == "delete"){

//cout << "seen delete" <<endl;

deleteRecord(head, second_word);

}

else{

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while ( i < line.length() && line[i] != ',') {

id.push_back(line[i]);

i++;

}

i++;

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while (i < line.length() && line[i] != ',') {

fn.push_back(line[i]);

i++;

}

i++;

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while (i < line.length() && line[i] != ',') {

ln.push_back(line[i]);

i++;

}

i++;

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while (i < line.length() && line[i] != ',') {

dob.push_back(line[i]);

i++;

}

i++;

while (i < line.length() && line[i] != ':') {

i++;

}

i++;

while (i < line.length() && line[i] != '}') {

gpa.push_back(line[i]);

i++;

}

ss << id;

ss << " ";

ss << gpa;

new_node->dob = dob;

new_node->fname = fn;

new_node->lname = ln;

new_node->next = NULL;

ss >> new_node->id;

ss >> new_node->gpa;

ss.clear();

if (head == NULL) {

head = new_node;

head->next = NULL;

}

else

{

node *cur = head;

while (cur->next != NULL) {

cur = cur->next;

}

cur->next = new_node;

}

}

}

void swap(node *first, node *second) {

node *temp = new node;

temp->dob = first->dob;

temp->fname = first->fname;

temp->gpa = first->gpa;

temp->id = first->id;

temp->lname = first->lname;

first->dob = second->dob;

first->fname = second->fname;

first->lname = second->lname;

first->id = second->id;

first->gpa = second->gpa;

second->dob = temp->dob;

second->fname = temp->fname;

second->lname = temp->lname;

second->id = temp->id;

second->gpa = temp->gpa;

}

void sortByFirstName(node *head){

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL)

{

if (cur1->fname > cur2->fname)

{

swap(cur1, cur2);

}

else if (cur1->fname == cur2->fname)

{

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void sortByLastName(node *head){

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL)

{

if (cur1->lname > cur2->lname)

{

swap(cur1, cur2);

}

else if (cur1->lname == cur2->lname)

{

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void sortByGpa(node *head){

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL) {

if (cur1->gpa > cur2->gpa)

{

swap(cur1, cur2);

}

else if (cur1->gpa == cur2->gpa)

{

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void sortByDOB(node *head) {

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL)

{

if (cur1->dob > cur2->dob)

{

swap(cur1, cur2);

}

else if (cur1->dob == cur2->dob)

{

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void sortByID(node *head){

node *cur1 = head;

node *cur2 = head;

while (cur1 != NULL)

{

cur2 = cur1->next;

while (cur2 != NULL) {

if (cur1->id > cur2->id)

{

swap(cur1, cur2);

}

cur2 = cur2->next;

}

cur1 = cur1->next;

}

}

void write(string file, node *head) {

ofstream ofs;

ofs.open(file.c_str());

if (ofs.is_open())

{

node *cur = head;

node *cur1 = head;

cur1 = cur->next;

while (cur != NULL && cur1 != NULL)

{

if (cur1->id != cur->id && cur->gpa == 4 || cur->gpa == 3 || cur->gpa == 2 || cur->gpa == 1 || cur->gpa == 0)

{

ofs << "{id:" << cur->id << ",first:" << cur->fname << ",last:" << cur->lname;

ofs << ",DOB:" << cur->dob << ",GPA:" << cur->gpa << ".0}";

ofs << endl;

cur = cur->next;

cur1 = cur1->next;

}

else if (cur1->id != cur->id) //when ids are not the same. print.

{

ofs << "{id:" << cur->id << ",first:" << cur->fname << ",last:" << cur->lname;

ofs << ",DOB:" << cur->dob << ",GPA:" << cur->gpa << "}";

ofs << endl;

cur = cur->next;

cur1 = cur1->next;

}

else //else ignore line

{

cur = cur->next;

cur1 = cur1->next;

}

if (cur1 == NULL) //print last line

{

if (cur->gpa == 4 || cur->gpa == 3 || cur->gpa == 2 || cur->gpa == 1 || cur->gpa == 0)

{

ofs << "{id:" << cur->id << ",first:" << cur->fname << ",last:" << cur->lname;

ofs << ",DOB:" << cur->dob << ",GPA:" << cur->gpa << ".0}";

ofs << endl;

}

else

{

ofs << "{id:" << cur->id << ",first:" << cur->fname << ",last:" << cur->lname;

ofs << ",DOB:" << cur->dob << ",GPA:" << cur->gpa << "}";

ofs << endl;

}

}

}

}

}

int main(int argc, char* argv[]){

node *head = NULL;

ifstream ifs,ifsSort;

string input;

string line;

// You can add code here to split file name from the command line

// For now, using static file names for input, sort and output

// "input=input12.txt;output=output12.txt;sort=sort12.txt"

ArgumentManager Arg = ArgumentManager( argc, argv, ';');

string inputfile = Arg.get("input");

string outputfile = Arg.get("output");

string sortfile = Arg.get("sort");

ifs.open(inputfile.c_str(), ios::in);

if (ifs.is_open() == false)

{

cout << " File Opening Error - Input File";

exit(0);

}

while (!ifs.eof())

{

getline(ifs, line);

addRecord(head, line);

}

//code to sort

ifsSort.open(sortfile.c_str(), ios::in);

if (ifsSort.is_open() == false)

{

cout << " File Opening Error - Sort File";

exit(0);

}

// To get last line from sort text file

// while (!ifsSort.eof())

// {

// cout << "line is " << line<< endl;

// getline(ifsSort, line);

// }

string lastline;

while (!ifsSort.fail()) {

getline(ifsSort, line );

if (!ifsSort.fail()) {

lastline = line;

}

}  

line = lastline;

cout << "last line is " << line<< endl;

int choice;

if (line == "id")

choice = 1;

else if (line == "first")

choice = 2;

else if (line == "last")

choice = 3;

else if (line == "DOB")

choice = 4;

else if (line == "GPA")

choice = 5;

//Note : In cpp switch can not take string as choice variable. we need to convert choice to integers first.

switch (choice) // run-time

{

case 1: // compile-time

sortByID(head);

break;

case 2: // compile-time

sortByFirstName(head);

break;

case 3: // compile-time

sortByLastName(head);

break;

case 4: // compile-time

sortByDOB(head);

break;

case 5: // compile-time

sortByGpa(head);

break;

default:

std::cout << "Invalid Sorting Criteria" << std::endl;

break;

};

//input = "output12.txt";

write(outputfile.c_str(), head); //delete duplicates and output the list

//system("pause");

int x;

cin >> x;

}

----------------input12.txt--------------

{id:1234567,first:Mary,last:Green,DOB:1996-10-03,GPA:4.0}

{id:1234568,first:Peter,last:White,DOB:1997-05-22,GPA:3.8}

{id:1654238,first:Nick,last:Park,DOB:1995-08-18,GPA:4.0}

{id:1234587,first:Katy,last:Green,DOB:1995-08-18,GPA:4.0}

{id:1234570,first:Peter,last:White,DOB:1997-05-22,GPA:3.8}

delete 1234568

----------------sort12.txt--------------

id

----------------outut12.txt--------------

{id:0,first:,last:,DOB:,GPA:3.8}

{id:1234567,first:Mary,last:Green,DOB:1996-10-03,GPA:4.0}

{id:1234570,first:Peter,last:White,DOB:1997-05-22,GPA:3.8}

{id:1234587,first:Katy,last:Green,DOB:1995-08-18,GPA:4.0}

{id:1654238,first:Nick,last:Park,DOB:1995-08-18,GPA:4.0}

command:

./sort "input=input12.txt;output=output13.txt;sort=sort12.txt"