Trying to make string array passed through methods C++ - c++

I'm trying to read names and ages from user, until user inputs "stop". Then just print all these values. Please help me , I'm just the beginner in C++
// Pass.cpp
// Reading names and ages from user and outputting them
#include <iostream>
#include <iomanip>
#include <cstring>
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using std::strcmp;
char** larger(char** arr);
int* larger(int* arr);
void read_data(char*** names, int** ages);
void print_data(char*** names, int** ages);
int main()
{
char** names = new char*[5];
char*** p_names = &names;
int* ages = new int[5];
int** p_ages = &ages;
read_data(p_names,p_ages);
print_data(p_names,p_ages);
}
void read_data(char*** names, int** ages)
{
const char* sent = "stop";
const int MAX = 15;
int count = 0;
char UI[MAX];
cout << "Enter names and ages."
<< endl << "Maximum length of name is " << MAX
<< endl << "When stop enter \"" << sent << "\".";
while (true)
{
cout << endl << "Name: ";
cin.getline(UI,MAX,'\n');
if (!strcmp(UI, sent))
break;
if (count + 1 > sizeof (&ages) / sizeof (&ages[0]))
{
*names = larger(*names);
*ages = larger(*ages);
}
*names[count] = UI;
cout << endl << "Age: ";
cin >> *ages[count++];
}
}
void print_data(char*** names, int** ages)
{
for (int i = 0; i < sizeof(*ages) / sizeof(*ages[0]);i++)
{
cout << endl << setw(10) << "Name: " << *names[i]
<< setw(10) << "Age: " << *ages[i];
}
}
char** larger(char** names)
{
const int size = sizeof(names) / sizeof(*names);
char** new_arr = new char*[2*size];
for (int i = 0; i < size; i++)
new_arr[i] = names[i];
return new_arr;
}
int* larger(int* ages)
{
const int size = sizeof(ages) / sizeof(*ages);
int* new_arr = new int[2 * size];
for (int i = 0; i < size; i++)
new_arr[i] = ages[i];
return new_arr;
}

You are really over complicating things.
Given the original problem:
Write a program that reads a number (an integer) and a name (less than
15 characters) from the keyboard. Design the program so that the data
is done in one function, and the output in another. Store the data in
the main() function. The program should end when zero is entered for
the number. Think about how you are going to pass the data between
functions
The problem wants you to think about passing parameters to functions. A simple solution would be:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
// Pass in a char array and an integer reference.
// These values will be modified in the function
void read_data(char name[], int& age)
{
cout << endl << "Age: ";
cin >> age;
cin.ignore();
cout << endl << "Name: ";
cin.getline(name, 16);
}
// Pass a const array and an int value
// These values will not be modified
void print_data(char const *name, int age)
{
cout << endl << setw(10) << "Name: " << name
<< setw(10) << "Age: " << age;
}
int main()
{
char name[16];
int age;
cout << "Enter names and ages."
<< endl << "Enter 0 age to quit.";
do {
read_data(name, age);
print_data(name, age);
} while (0 != age)
}
EDIT: Modified per user3290289's comment
EDIT2: Storing data in an array
// Simplify by storing data in a struct (so we don't have to manage 2 arrays)
struct Person {
char name[16];
int age;
};
// Returns how many People were input
int read_data(Person*& arr)
{
int block = 10; // How many persons to allocate at a time
arr = NULL;
int arr_size = 0;
int index = 0;
while (true) {
if (index == arr_size) {
arr_size += block;
arr = (Person *)realloc(arr, arr_size * sizeof(Person)); // Reallocation
// Should check for error here!
}
cout << endl << "Age: ";
cin >> arr[index].age;
cin.ignore();
if (0 == arr[index].age) {
return index;
}
cout << endl << "Name: ";
cin.getline(arr[index++].name, 16);
}
}
void print_data(Person *arr, int count)
{
for (int i = 0; i < count; i++) {
cout << endl << setw(10) << "Name: " << arr[i].name
<< setw(10) << "Age: " << arr[i].age;
}
}
int main()
{
Person *arr;
int count = read_data(arr);
print_data(arr, count);
free(arr); // Free the memory
}

try this:
#include <iostream>
#include <iomanip>
#include <vector>
#include <sstream>
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using std::strcmp;
void read_data(std::vector<std::string> &names, std::vector<int> &ages);
void print_data(std::vector<std::string> &names, std::vector<int> &ages);
int main()
{
std::vector<std::string> names;
std::vector<int> ages;
read_data(names, ages);
print_data(names, ages);
}
void read_data(std::vector<std::string> &names, std::vector<int> &ages)
{
const char* sent = "stop";
cout << "Enter names and ages."
<< endl << "When stop enter \"" << sent << "\".";
while (true)
{
std::string input;
cout << endl << "Name: ";
std::getline(cin, input);
if (!strcmp(input.c_str(), sent))
break;
names.push_back(input);
cout << endl << "Age: ";
std::string age;
std::getline(cin, age);
ages.push_back(atoi(age.c_str()));
}
}
void print_data(std::vector<std::string> &names, std::vector<int> &ages)
{
for (int i = 0; i < names.capacity() ; i++)
{
cout << endl << setw(10) << "Name: " << names.at(i)
<< setw(10) << "Age: " << ages.at(i);
}
}

One problem I see is this if statement:
if (count + 1 > sizeof (&ages) / sizeof (&ages[0]))
&ages is the address of an int**, a pointer, and so it's size is 8 (usually) as that is the size of a pointer type. The function does not know the size of the array, sizeof will only return the correct answer when ages is declared in the same scope.
sizeof(&ages) / sizeof(&ages[0])
will always return 1

I believe one natural solution about this problem is as follows:
create a "std::map" instance. Here std::map would sort the elements according to the age. Here my assumption is after storing the data into the container, you would like to find about a particular student age/smallest/largest and all various manipulation with data.Just storing and printing the data does not make much sense in general.
create a "std::pair" and take the both input from the user into the std::pair "first" and "second" member respectively. Now you can insert this "std::pair" instance value into the above "std::map" object.
While printing, you can now fetch the each element of "std::map" in the form of "std::pair" and then you can display pair "first" and "second" part respectively.

Related

c++ program printing out address instead of value

I have a program that takes in information through a struct and puts it into a vector, and I'm trying to print that information out but instead get an address. The structure should hold the values correctly so I think it's either my pointers or the way I'm printing it out.
#include <iostream>
#include <cstring>
#include<vector>
using namespace std;
struct student
{
char* fName;
char* lName;
int id;
float gpa;
};
void add(vector<student*>*);
int main()
{
vector <student*>* list = new vector<student*>();
if (strcmp(cmd,"ADD") == 0)
{
add(list);
}
else if (strcmp(cmd,"PRINT") == 0)
{
for(vector<student*>::iterator i = list->begin(); i != list->end(); i++)
{
cout << *i;
}
cout << "print" << endl;
}
}
void add(vector<student*>* paramlist)
{
student* s = new student();
s->fName = new char[25];
s->lName = new char[25];
cout << "Enter first name" << endl;
cin >> s->fName;
cout << "Enter last name" << endl;
cin >> s->lName;
cout << "Enter id number" << endl;
cin >> s->id;
cout << "Enter GPA" << endl;
cin >> s->gpa;
paramlist->push_back(s);
}
Or it might have something to do with the way I iterate through the vector.
You need to add an operator overload for your struct, to define how the struct should appear when printed. You also need to dereference the pointer as well as the iterator.
// Define how the struct should look when printed.
// This function makes it appear like:
// Name: John Smith, ID: 1235, GPA: 4.0
std::ostream &operator<<(std::ostream &os, const student &val) {
os
<< "Name: " << val.fname << " " << val.lname
<< ", ID: " << val.id
<< ", GPA: " << val.gpa
<< endl;
return os;
}
Then later...
for(vector<student*>::iterator i = list->begin(); i != list->end(); i++)
{
// Dereference twice, once for the iterator, and again for the pointer.
cout << **i << endl;
}
You have to dereference twice **i.
With *i you get the address of vector<student*> element that is student*.
You get student, you need other *.
You may use for (auto i: list) to make your life easier.

Getting average age of students and youngest student's name

I'm having some trouble with getting the average age of all students including getting the youngest student's name outputted. The output is supposed to come from a function call I wrote called ageCalc(...).
main.cpp
#include <iostream>
#include <fstream>
#include <iomanip>
#include "Student1.h"
#include "Student2.h"
#include "ageCalc.h"
using namespace std;
const int SIZE = 100;
int main()
{
ifstream inFile;
inFile.open("C:\\COMSC200\\a2data.input", ios::in|ios::binary);
// Open the input file – if it fails to open, display an error message and terminate
if(!inFile.is_open())
{
cout << "Unable to open file!";
return 1;
}
else
{
cout << "File successfully open!\n\n";
}
// Use a pointer array to manage all the created student variables.
Student1 **ptrArr = new Student1 *[SIZE];
Student1 s;
int total = 0;
// read the first input record
inFile.read(reinterpret_cast<char *> (&s), sizeof(s));
while(!inFile.eof())
{
// dynamically allocate space for new student variable
ptrArr[total] = new Student1;
// populate the student variable from the input
*ptrArr[total] = s;
total++;
// read the next input record
inFile.read(reinterpret_cast<char *> (&s), sizeof(s));
}
Student2 *st = new Student2[SIZE];
for(int i = 0; ptrArr[i]; i++)
{
for(char fn: ptrArr[i]->first_name)
st[i].fn += fn;
st[i].mi = ptrArr[i]->middle_int[0];
for(char ln: ptrArr[i]->last_name)
st[i].ln += ln;
st[i].cc = ptrArr[i]->campus_code;
for(char sID: ptrArr[i]->student_ID)
st[i].sID += sID;
st[i].age = atoi(ptrArr[i]->age);
}
cout << "First Name" << setw(9)
<< "MI" << setw(15)
<< "Last Name" << setw(17)
<< "Campus Code" << setw(16)
<< "Student ID" << setw(15)
<< "Age" << endl;
cout << "===================================================================================" << endl;
for(int j = 0; st[j].age != 0; j++)
{
cout << st[j].fn << setw(8);
cout << st[j].mi << " ";
cout << st[j].ln << setw(2);
cout << st[j].cc << " ";
cout << st[j].sID << setw(16);
cout << st[j].age << " " << endl;
}
Student2 *y;
int avg = ageCalc(&st, y);
cout << "Average student age is: " << avg << " years." << endl;
cout << "Youngest student is: " << arr[i]->fn << " " << arr[i]->mi << " " << arr[i]->ln << endl;
for(int x = 0; ptrArr[x]; x++)
{
delete ptrArr[x];
}
delete [] st;
inFile.close();
return 0;
}
ageCalc.cpp
#include "Student2.h"
using namespace std;
int ageCalc(Student2 *arr[], Student2 *&y)
{
int i = 0, sum = 0, index = 0, avg;
while(arr[i] != nullptr)
{
sum = arr[i]->age + sum;
i++;
if(arr[i]->age < arr[index]->age)
{
index = i;
}
}
y = arr[index];
avg = sum / i;
return avg;
}
Student1.h
#ifndef STUDENT1_H_
#define STUDENT1_H_
#include <iostream>
using namespace std;
struct Student1
{
char first_name[10];
char middle_int[10];
char last_name[20];
char campus_code;
char student_ID[8];
char age[3];
};
#endif
Student2.h
#ifndef STUDENT2_H_
#define STUDENT2_H_
#include <iostream>
#include <string>
using namespace std;
struct Student2
{
string fn;
char mi;
string ln;
char cc;
string sID;
short int age;
};
#endif
ageCalc.h
#ifndef AGECALC_H_
#define AGECALC_H_
#include "Student2.h"
int ageCalc(Student2 *[], Student2 *&);
#endif

Array is getting trash after a new raw is added to a file С++ Visual Studio

I'm trying to solve a task with structs, dynamic arrays and files. So I'm
creating a dynamic array - Unit* array_of_employees = new Unit[number_of_employees];
generating an array - generateEmployees(Unit* array_of_employees, int& number_of_employees);
writing the data into the file - writeFileEmployees(Unit* array_of_employees, int number_of_employees);
showing elements of array in console - readAllEmployeeData(Unit* array_of_employees, int number_of_employees);
It is working correct till that moment. Then I'm
redistributing the array's memory by creating a new array with a +1 memory size - Unit* getRememberForArrayOfEmployees(Unit* array_of_employees, int& number_of_employees, int new_number_of_employees);
adding a new note in the end of the array
writing it in the end of the file - void writeEndFileEmployees(Unit new_epmloyee);
Then I'm trying to show the array in console, but there is trash in array. Need your help
#include <conio.h>
#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
struct Unit
{
string fullName;
string department;
string position;
int monthSalary;
};
const string FILE_OF_EMPLOYEES = "employee.txt"; //file_path
int getCountOfEmployees(string FILE_OF_EMPLOYEES);
void generateEmployees(Unit* array_of_employees, int& number_of_employees);
void writeFileEmployees(Unit* array_of_employees, int number_of_employees);
void writeEndFileEmployees(Unit new_epmloyee);
void readAllEmployeeData(Unit* array_of_employees, int number_of_employees);
void addNewEmployeeData(Unit* array_of_employees, int& number_of_employees);
Unit* getRememberForArrayOfEmployees(Unit* array_of_employees, int& number_of_employees, int new_number_of_employees);
int main()
{
setlocale(LC_ALL, "rus");
int number_of_employees = getCountOfEmployees(FILE_OF_EMPLOYEES);
Unit* array_of_employees = new Unit[number_of_employees];
generateEmployees(array_of_employees, number_of_employees);
writeFileEmployees(array_of_employees, number_of_employees);
readAllEmployeeData(array_of_employees, number_of_employees);
addNewEmployeeData(array_of_employees, number_of_employees);
//From this place there is trash in the array_of_employees :(
readAllEmployeeData(array_of_employees, number_of_employees);
delete[]array_of_employees;
system("pause");
return 0;
}
//Define amount of structures in the file
int getCountOfEmployees(string FILE_OF_EMPLOYEES)
{
//Open and move a cursor in the end of the file
ifstream file(FILE_OF_EMPLOYEES, ios::in);
int number_of_strings = 0;
if (file.is_open())
{
string buffer;
while (getline(file, buffer))
number_of_strings++;
}
file.close();
return number_of_strings;
}
void generateEmployees(Unit* array_of_employees, int& number_of_employees)
{
number_of_employees = 1;
array_of_employees[0].fullName = "Ivanov";
array_of_employees[0].department = "QA1";
array_of_employees[0].position = "QA";
array_of_employees[0].monthSalary = 1000;
}
void writeFileEmployees(Unit* array_of_employees, int number_of_employees)
{
ofstream fout(FILE_OF_EMPLOYEES, ios::out);
for (int i = 0; i < number_of_employees; i++)
{
fout << array_of_employees[i].fullName << " "
<< array_of_employees[i].department << " "
<< array_of_employees[i].position << " "
<< array_of_employees[i].monthSalary;
if (i < number_of_employees - 1) fout << endl;
}
fout.close();
}
void writeEndFileEmployees(Unit new_employee)
{
ofstream fadd(FILE_OF_EMPLOYEES, ios::app);
fadd << endl;
fadd << new_employee.fullName << " "
<< new_employee.department << " "
<< new_employee.position << " "
<< new_employee.monthSalary;
fadd.close();
cout << "New employee added" << endl;
}
void readAllEmployeeData(Unit* array_of_employees, int number_of_employees)
{
//system("cls");
cout << " Users accounts\n"
<< " ------------------------------- \n"
<< "|Full Name"
<< "\t|Department"
<< "\t|Position"
<< "\t|Monthly Salary\t|\n"
<< "\n ------------------------------- \n";
for (int i = 0; i < number_of_employees; i++)
{
cout << "|" << array_of_employees[i].fullName << " "
<< "\t|" << array_of_employees[i].department << "\t"
<< "\t|" << array_of_employees[i].position << "\t"
<< "\t|" << array_of_employees[i].monthSalary << "\t|"
<< endl;
}
cout << " ------------------------------- " << endl;
}
void addNewEmployeeData(Unit* array_of_employees, int& number_of_employees)
{
//system("cls");
array_of_employees = getRememberForArrayOfEmployees(array_of_employees, number_of_employees, number_of_employees + 1);
cout << "Add new user profile\n" << endl;
cout << "Full Name: ";
cin >> array_of_employees[number_of_employees - 1].fullName;
cout << "Department: ";
cin >> array_of_employees[number_of_employees - 1].department;
cout << "Position: ";
cin >> array_of_employees[number_of_employees - 1].position;
cout << "Monthly salary: ";
cin >> array_of_employees[number_of_employees - 1].monthSalary;
writeEndFileEmployees(array_of_employees[number_of_employees - 1]);
}
Unit* getRememberForArrayOfEmployees(Unit* array_of_employees, int& number_of_employees, int new_number_of_employees)
{
Unit* new_array_of_employees;
if (number_of_employees < new_number_of_employees)
{
new_array_of_employees = new Unit[new_number_of_employees];
for (int i = 0; i < number_of_employees; i++)
{
new_array_of_employees[i].fullName = array_of_employees[i].fullName;
new_array_of_employees[i].department = array_of_employees[i].department;
new_array_of_employees[i].position = array_of_employees[i].position;
new_array_of_employees[i].monthSalary = array_of_employees[i].monthSalary;
}
for (int i = number_of_employees; i < new_number_of_employees; i++)
{
new_array_of_employees[i].fullName = " ";
new_array_of_employees[i].department = " ";
new_array_of_employees[i].position = " ";
new_array_of_employees[i].monthSalary = 0;
}
delete[]array_of_employees;
number_of_employees = new_number_of_employees;
array_of_employees = new_array_of_employees;
}
return array_of_employees;
}
addNewEmployeeData (via the call to getRememberForArrayOfEmployees) can delete the existing array_of_employees data. You allocate a new array for this, but never pass the modified pointer back to the caller.
You should pass array_of_employees as a reference (Unit *&array_of_employees) like you do with number_of_employees.

Class object will not push_back onto vector

Compiles and everything except adding in a 'ship'
Constructor for ship
Ship::Ship(std::string name, int length, std::string show) {
std::string _name = name;
int _length = length;
std::string _show = show;
}
void Ships::buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
addShip(ship);
}
void Ships::addShip(Ship &ship) {
ships.push_back(ship);
}
I'm sure it's something very obvious, I've searched the web and found nothing helpful. I only took snippets from my code if anything else is needed let me know. Thanks in advance!
/Ship.h
#pragma once
#include <string>
class Ship {
std::string _name;
int _length;
std::string _show;
public:
Ship(){
std::string name = _name;
int length = _length;
std::string show = _show;
};
Ship(std::string _name, int _length, std::string _show);
std::string getName();
int getLength();
std::string getShow();
};
/Ship.cpp
#include <string>
#include "Ship.h"
Ship::Ship(std::string name, int length, std::string show) {
std::string _name = name;
int _length = length;
std::string _show = show;
}
std::string Ship::getName() {
return _name;
}
int Ship::getLength() {
return _length;
}
std::string Ship::getShow() {
return _show;
}
/Ships.h
#pragma once
#include <vector>
#include "Ship.h"
class Ships {
std::vector<Ship> ships;
public:
void addShip(Ship &ship);
int getCount();
Ship getLongestShip();
void buildShip();
int getNumberOfShipsLongerThan(int input);
void displayShips();
};
/Ships.cpp
#include "Ships.h"
#include <iostream>
void Ships::addShip(Ship &ship) {
ships.push_back(ship);
}
int Ships::getCount() {
return ships.size();
}
Ship Ships::getLongestShip() {
Ship longestShip = ships[0];
for (Ship aShip : ships) {
if (longestShip.getLength() < aShip.getLength())
longestShip = aShip;
}
std::cout << "The longest ship is the " << longestShip.getName() << std::endl;
std::cout << "From end to end the length is " << longestShip.getLength() << std::endl;
std::cout << "The show/movie it is from is " << longestShip.getShow() << std::endl;
return longestShip;
}
int Ships::getNumberOfShipsLongerThan(int input) {
int longerThan = 0;
int size = ships.size();
for (int i = 0; i < size; i++) {
if (input < ships[i].getLength())
longerThan++;
}
return longerThan;
}
void Ships::displayShips() {
std::cout << " Complete Bay Manifest " << std::endl;
std::cout << "***********************" << std::endl;
for (int i = 0; i < ships.size(); i++) {
int a = i + 1;
std::cout << "Ship (" << a << ")" << std::endl;
std::cout << "Name: " << ships[i].getName() << std::endl;
std::cout << "Length: " << ships[i].getLength() << std::endl;
std::cout << "Show: " << ships[i].getShow() << std::endl<<std::endl;
}
}
void Ships::buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
addShip(ship);
}
/driver.cpp
#include <iostream>
#include "Ship.h"
#include "Ships.h"
void menu();
Ship buildShip();
void shipsInBay(Ships &ships);
void processDirective(int choice, Ships &ships);
void longerThan(Ships &ships);
int main() {
std::cout << "Welcome to Daniel Mikos' Ship Bay!" << std::endl << std::endl;
menu();
system("PAUSE");
return 0;
}
void menu() {
Ships ships;
int choice = 0;
std::cout << "Please make a selection" << std::endl;
std::cout << " (1) Add a ship to the bay" << std::endl;
std::cout << " (2) How many ships are already in the bay?" << std::endl;
std::cout << " (3) Which ship is the longest? " << std::endl;
std::cout << " (4) Ships longer than ___? " << std::endl;
std::cout << " (5) Manifest of all ships currently logged" << std::endl;
std::cout << " (6) Exit" << std::endl;
std::cout << " Choice: ";
std::cin >> choice;
processDirective(choice, ships);
}
Ship buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
return ship;
}
void shipsInBay(Ships &ships) {
int count = ships.getCount();
std::cout << std::endl;
std::cout << "There is currently " << count;
std::cout << " ship(s) in bay" << std::endl << std::endl;
}
void longerThan(Ships &ships) {
int input = 0;
std::cout << "Find ships longer than? ";
std::cin >> input;
std::cout << "There are " << ships.getNumberOfShipsLongerThan(input) << "longer than " << input << "feet";
}
void processDirective(int choice, Ships &ships) {
if (choice == 1)
buildShip();
if (choice == 2)
shipsInBay(ships);
if (choice == 3)
ships.getLongestShip();
if (choice == 4)
longerThan(ships);
if (choice == 5)
ships.displayShips();
menu();
}
There is all of my code
To add an object to a vector of objects use emplace_back() and pass the constructor arguments as arguments to emplace back. It will then build the object in place so call:
ships.emplace_back(name, length, show);
to construct your ship object in place. Your constructor also is incorrect as pointed out by #Kevin. You need to change it to:
this->_name = name;
this->_length = length;
this->_show = show;
assuming I've guessed your class design correctly.
EDIT
Tried to build a minimum example from this and this works fine for me:
Header.h
class Ship {
std::string _name;
int _length;
std::string _show;
public:
Ship();
Ship(std::string _name, int _length, std::string _show);
std::string getName();
int getLength();
std::string getShow();
};
class Ships {
public:
void addShip(Ship &ship);
void buildShip();
std::vector<Ship> ships;
};
and Source.cpp
#include "Header.h"
Ship::Ship(std::string name, int length, std::string show) {
this->_name = name;
this->_length = length;
this->_show = show;
}
void Ships::buildShip() {
std::string name = "Name";
std::string show = "Show";
int length = 0;
ships.emplace_back(name, length, show);
}
int main(int argc, char argv[])
{
Ships ships;
ships.buildShip();
std::cout << "Number of ships = " << ships.ships.size() << std::endl;
return 0;
}
Prints Number of ships = 1. Can you slim it down to something like this?

How to Access a variable in a filestream loaded in list container

I am the new kid in the block, studying C++. I have loaded a file stream in a list container, using variables. I want to be able to access and change the value of any of those variables. I've been trying for weeks to no avail. Can somebody help?
This is the external text file: flightBoard1.txt
Delta 3431 Paris JFK
Usair 2275 EWR London
Delta 1500 Bonn Milan
This is the main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <list>
using namespace std;
template<class T, class U, class V>
void changeFlight(list<string> &myFlight, T loc, U value, V newVal);
int main()
{
string _company;
int _flight;
string _origin;
string _destination;
list<string> flightBoard;
stringstream *ssPtr;
int counter = 0;
ifstream myFile("flightBoard1.txt");
while(myFile >> _company >> _flight >> _origin >> _destination ){
++counter;
ssPtr = new stringstream; // you want to put each line in a different slot in the flightBoard list object
*ssPtr << counter << " " << _company << "\t" << _flight << "\t" << _origin << "\t" << _destination << endl;
flightBoard.push_back(ssPtr->str()); // You need an arrow, this is a pointer
}
list<string>::iterator it;
for(it = flightBoard.begin(); it != flightBoard.end(); it++){
cout << *it ;
}
int oldFlight, newFlight;
cout << endl << "Enter old flight number: ";
cin >> oldFlight;
cout << "Enter new flight number: ";
cin >> newFlight;
changeFlight(flightBoard, ssPtr, oldFlight, newFlight);
delete ssPtr;
myFile.close();
return 0;
}
template<class T, class U, class V>
void changeFlight(list<string> &myFlight, T loc, U value, V newVal){
list<string>::iterator it;
cout << endl << "Flight: " << value << " has been changed to: " << newVal << endl;
for(it = myFlight.begin(); it != myFlight.end(); it++){
// THIS IS WHERE I AM HAVING A PROBLEM
// PLEASE UN-COMMENT BELOW TO SEE PROBLEM
/*if(it -> myFlight -> loc -> value){
value = newVal;
}*/
}
}
To solve your problem I think you should use the better structure for storage of your flights. string is not a good type if you need to manipulate data further. I suggest to introduce class Flight:
class Flight
{
public:
string company;
int flight;
string origin;
string destination;
Flight(const string& _company, int _flight, const string& _origin, const string& _destination)
: company(_company), flight(_flight), origin(_origin), destination(_destination)
{
}
string ToString() const
{
stringstream printer;
printer << company << "\t" << flight << "\t" << origin << "\t" << destination << endl;
return printer.str();
}
};
Also there are a number of problems in code snippet you have posted.
Memory leak inside while loop. You are allocating ssPtr = new stringstream; on each iteration, but delete it only once at the end.
changeFlight has too much template type arguments. If U value should be changed to V newVal inside changeFlight probably it should have the same types.
Hard to change type of flightBoard, list<string> copied everywhere. It's better to create typedef for list<string> type to make your code simpler. E.g. typedef list<string> FlightListType;.
Here is your code with all the mentioned problems fixed:
typedef list<Flight> FlightListType;
template<class T>
void changeFlight(FlightListType& myFlight, T value, T newVal);
int main()
{
string _company;
int _flight;
string _origin;
string _destination;
FlightListType flightBoard;
ifstream myFile("flightBoard1.txt");
while(myFile >> _company >> _flight >> _origin >> _destination )
{
flightBoard.push_back(Flight(_company, _flight, _origin, _destination));
}
FlightListType::const_iterator it;
int counter = 0;
for(it = flightBoard.begin(); it != flightBoard.end(); it++)
{
cout << counter << " " << (*it).ToString();
++counter;
}
int oldFlight, newFlight;
cout << endl << "Enter old flight number: ";
cin >> oldFlight;
cout << "Enter new flight number: ";
cin >> newFlight;
changeFlight(flightBoard, oldFlight, newFlight);
myFile.close();
return 0;
}
template<class T>
void changeFlight(FlightListType& myFlight, T value, T newVal)
{
FlightListType::iterator it;
cout << endl << "Flight: " << value << " has been changed to: " << newVal << endl;
for(it = myFlight.begin(); it != myFlight.end(); it++)
{
if ((*it).flight == value)
{
// TODO: Here you can do with the Flight what ever you need
// For example change it's number
(*it).flight = newVal;
}
}
}