Enlarge a dynamic array (no vector<> allowed, class assignment) - c++

This is my first problem to ask about, please scrutinize me if necessary :)
I'm trying to solve a problem for a C++ class at school. I have encountered an error I really can't grasp. I'm in taking my baby steps in programming.
The assignment says:
two classes,
inheritance mechanism used,
database holding students using dynamic memory allocation,
a way of enlarging the database without using advanced data structures,
overload stream operators for objects of created class.
This is my code:
#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
protected:
char Name[20];
string Surname;
int Age;
public:
virtual void whoAmI()=0;
friend ostream &operator<< (ostream &out_, Person &s); // stream overl.
friend istream &operator>> (istream &in_, Person &s);
friend void resizeArr(Person* oldList, int oldSize, int newSize); // array enlarge
};
class Student :public Person
{
public:
Student(){}
Student(char name[], string surname, int age )
{
strcpy(Name, name);
Surname = surname;
Age = age;
}
virtual void whoAmI() // basically replaced by overloaded ostream
{
//cout << "I am a student\nMy name is " << name <<" "<< surname << "; I'm "<< age << " years old.";
cout << Name << endl;
cout << Surname << endl;
cout << Age << endl;
}
};
istream &operator>> (istream &in_, Person &s) // through reference: stream object and overloading object
{
cout << "New student record: "<< endl;
cout << "Name: " << endl;
in_ >> s.Name;
cout << "Surname: " << endl;
in_ >> s.Surname;
cout << "Age: " << endl;
in_ >> s.Age;
cout << endl;
return in_;
}
ostream &operator<< (ostream &out_, Person &s)
{
out_ << "Name:\t\t" << s.Name << endl << "Surname:\t" << s.Surname << endl <<"Age:\t\t" << s.Age << endl;
return out_;
}
void resizeArr(Student* oldList, int oldSize, int newSize)
{
Student *newList = new Student[newSize];
for(int i = 0; i < oldSize; i++) // COPYING
{
newList[i]=oldList[i];
}
for(int i = oldSize ; i < newSize ; i++) // init rest as blank students to avoid errors
{
newList[i] = Student( "undef" , "undef", 0);
}
delete [] oldList; // free memory used for old array
oldList = newList; // reset pointer to new array
}
int main()
{
int initSize = 2;
int plusSize = 4;
Student *list1 = new Student[initSize];
for (int i=0; i<initSize; i++){ // initialize each cell as a blank student
list1[i] = Student( "undef" , "undef", 0);
}
for (int i=0; i<initSize; i++) // display initial array
{
cout << list1[i] << endl << "------------------------------" << endl; // for the sake of console output clarity
}
resizeArr(list1, initSize, plusSize); // FUNCTION CALL
cout << endl << "\tEnlarger database: " << endl << endl; // for the sake of console output clarity
for (int i=0; i<plusSize; i++) // display enlarged array
{
cout << list1[i] << endl << "------------------------------" << endl; // for the sake of console output clarity
}
getch();
return 0;
}
I have previously prototyped such a mechanism using integer arrays and it worked... now I'm getting a crash for an unknown reason.
Please point me in the right direction.
Edit:
The program compiles and runs, the new array seems to hold the first two elements of the old array, and by the point it reaches the first new element, the program crashes (the memory cell seems to be trolling me and holds a smiley face).
The first two Student objects are copied, the third element causes an error:

The issue lies in the definition of your resize function:
void resizeArr(Student* oldList, int oldSize, int newSize)
Unless otherwise noted, all parameters passed to a function are by value. Even though the first parameter is a pointer, that only allows to modify the memory to which it is pointing, not the pointer itself.
You need to change the declaration of the first parameter to either Student **, with code changed in the method to handle the double dereference, or change it to Student*&.
I suspect that you were lucky that it worked for integer.

You are passing a pointer to a student list to your resizeArr routine, i.e. void resizeArr(Student* oldList, int oldSize, int newSize), but not a pointer to a pointer.
Hence, assigning a new/different memory block to the pointer within resizeArr will let the variable within resizeArr point to the new address, but the pointer that has been passed to resizeArr (i.e list1) is not changed.
I'd suggest to change the logic to Student* resizeArr(Student* oldList, int oldSize, int newSize) and call it like list1 = resizeArr(list1, initSize, plusSize);
This is analogous to the signature of void* realloc (void* ptr, size_t size);.

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.

Beginner C++ - Having trouble compiling my code [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
EDIT: Working code below
I'll paste my code below, but if someone could please explain to me why what's happening is happening instead of simply writing me out an answer, that'd be much appreciated, thank you!
Im having a compilation error, telling me there is no instance of overloaded function. I can circumvent this compilation error by commenting out the line cin.get(Kingdom.m_name, 32, '\n');, but this is obviously useless, because now my program just terminates after entering the name of the first Kingdom.
I assume the line void read(sict::Kingdom& Kingdom) forces the computer to cycle through my Kingdom array, based on user input.
//header file
#ifndef KINGDOM_H
#define KINGDOM_H
#include <cstdlib>
// TODO: sict namespace
namespace sict
{
// TODO: define the structure Kingdom in the sict namespace
struct Kingdom {
char m_name[32];
int m_population;
};
// TODO: declare the function display(...),
// also in the sict namespace
void display(const Kingdom& pKingdom);
void display(const Kingdom kingdoms[], size_t count);
}
#endif
`
//implementation .cpp
#include <iostream>
#include <cstdlib>
#include "Kingdom.h"
using namespace std;
// TODO: the sict namespace
namespace sict
{
// TODO:definition for display(...)
void display(const Kingdom& pKingdom) {
cout << pKingdom.m_name << ", " << "population " << pKingdom.m_population << endl;
}
void display(const Kingdom kingdoms[], size_t count) {
cout << "------------------------------" << endl;
cout << "Kingdoms of SICT" << endl;
cout << "------------------------------" << endl;
int pop = 0;
for (size_t i = 0; i < count; i++) {
cout << i + 1 << ". ";
display(kingdoms[i]);
pop += kingdoms[i].m_population;
}
cout << "------------------------------" << endl;
cout << "Total population of SICT: " << pop << endl;
cout << "------------------------------";
}
}
And my main,
#include <iostream>
#include <cstring> //for size_t definition
#include <vector>
#include "Kingdom.h"
using namespace std;
using namespace sict;
void read(Kingdom&);
int main() {
int count = 0; // the number of kingdoms in the array
// TODO: declare the pKingdom pointer here (don't forget to initialize it)
Kingdom *pKingdom = nullptr;
cout << "==========\n"
<< "Input data\n"
<< "==========\n"
<< "Enter the number of Kingdoms: ";
cin >> count;
cin.ignore();
if (count < 1) return 1;
// TODO: allocate dynamic memory here for the pKingdom pointer
pKingdom = new Kingdom[count];
for (int i = 0; i < count; ++i) {
cout << "Kingdom #" << i + 1 << ": " << endl;
// TODO: add code to accept user input for Kingdom i
read(pKingdom[i]);
}
cout << "==========" << endl << endl;
// testing that "display(...)" works
cout << "------------------------------" << endl
<< "The 1st Kingdom entered is" << endl
<< "------------------------------" << endl;
display(pKingdom[0]);
cout << "------------------------------" << endl << endl;
// expand the array of Kingdoms by 1 element
count = count + 1;
Kingdom *cpy_pKingdom = nullptr;
// TODO: allocate dynamic memory for count + 1 Kingdoms
cpy_pKingdom = new Kingdom[count];
// TODO: copy elements from original array into this newly allocated array
for (int i = 0; i < count; i++) {
cpy_pKingdom[i] = pKingdom[i];
}
// TODO: deallocate the dynamic memory for the original array
delete[] pKingdom;
// TODO: copy the address of the newly allocated array into pKingdom pointer
pKingdom = cpy_pKingdom;
// add the new Kingdom
cout << "==========\n"
<< "Input data\n"
<< "==========\n";
cout << "Kingdom #" << count << ": " << endl;
// TODO: accept input for the new element in the array
read(pKingdom[count - 1]);
cout << "==========\n" << endl;
// testing that the overload of "display(...)" works
display(pKingdom, count);
cout << endl;
// TODO: deallocate the dynamic memory here
//delete[] pKingdom;
//delete[] cpy_pKingdom;
getchar();
return 0;
}
// read accepts data for a Kingdom from standard input
//
void read(Kingdom& pkingdom) {
cout << "Enter the name of the Kingdom: ";
cin.get(pkingdom.m_name, 32, '\n');
cin.ignore(2000, '\n');
cout << "Enter the number of people living in " << pkingdom.m_name << ": ";
cin >> pkingdom.m_population;
cin.ignore(2000, '\n');
This can be quite the headache, and my hat goes off to all programmers out there that have all gone through this.
There are six overloads of istream::get. The arguments you are passing don't match any of them. That's why the compiler fails to compile that line.
The problem is that you are using char for the name member variable of Kingdom. That does not sound right. A name is usually a string. It char cannot be used to represent a name.
You can change name to be of type std::string or an array of char. If you use an array of char, you can use the function call like you have.
struct Kingdom {
char m_name[32]; // Since you are passing 32 to cin.get
int m_population;
};
You use std::string for name, you need to use std::getline.
struct Kingdom {
std::string m_name;
int m_population;
};
and ...
std::getline(std::cin, Kingdom.m_name);
I would recommend using std::string. They are much easier to work with.
istream::get has the following overloads (courtesy of http://en.cppreference.com/w/cpp/io/basic_istream/get):
(1) int_type get();
(2) basic_istream& get( char_type& ch );
(3) basic_istream& get( char_type* s, std::streamsize count );
(4) basic_istream& get( char_type* s, std::streamsize count, char_type delim );
(5) basic_istream& get( basic_streambuf& strbuf );
(6) basic_istream& get( basic_streambuf& strbuf, char_type delim );
You are calling get with three arguments, and out of the overloads above, only (4) matches.
As you can see, it expects a char pointer as its first argument, where as you are passing a char. (m_name)
I think you meant to define m_name as a char array (char m_name[128] for example), since that would be much more reasonable.

arry of pointers ( classes )

So I have these classes:
In main I wrote an array of pointers:
student *arry[10];
How can I make each cell point to an object of a different class?
For example :
I want the cell 0 , 2 , 4
point to an object of class medstudent
using ( new statement )
thank you
here is class medStudent
#include<iostream>
#include"student.cpp"
using namespace std;
class medStudent:public student {
public :int clinicH;
public:
medStudent(int ch, string n , int i ):student(n,i){
setClinicH(ch);
cout << "New Medecine Student" << endl;
}
~medStudent(){
cout << "Medecine Student Deleted" << endl;
}
medStudent(medStudent & ms):student(ms){
cout << "New Copy Medecined Student" << endl;
}
medstudent(){
}
void setClinicH(int ch){
clinicH = ch;
}
int getClinicH()const{
return clinicH;
}
void print()const{
student::print();
cout << "Clinical Hours: " << getClinicH() << endl;
}
};
Here is class student:
#include <iostream>
//#include"medstudent.cpp"
using namespace std;
class student//:public medstudent
{
public :
static int numberOfSaeeds;
const int id;
string name;
public:
~student(){
cout << "Delete Student: " << getName() << " " << endl ;
}
student(string n, int i):id(i){
setName(n);
cout << "Student with args" << endl ;
}
void setName(string n){
name = n;
}
string getName()const{
return name;
}
void print()const{
cout << "My name is: " << name << endl;
cout << "My ID is: " << id << endl;
}
void setNOS(int nos){
numberOfSaeeds = nos;
}
int getNOS(){
return numberOfSaeeds;
}
void printAddress()const{
cout << "My address is " << this << endl;
}
student * getAddress(){
return this;
}
student(student & sc):id(sc.id){
name = sc.name;
setName(sc.getName());
cout << "New Object using the copy constructor" << endl;
}
};
Here is main code:
#include<iostream>
using namespace std;
#include"time.cpp"
#include "student.cpp"
//#include"medstudent.cpp"
int main(){
student a1("asa" , 2);
student * a[10];
a[3]= new student("jj", 22 );
a[0] = new medStudent();
}
Since you explicitly declare a medStudent constructor the compiler will not create a default constructor for your class. And when you do new medStudent(); you are (explicitly) trying to invoke the default constructor, which doesn't exist.
That will give you a build error, one that should have been very easy to diagnose if you read it and most importantly shown it to us (when asking questions about build errors, always include the complete and unedited error output, including any informational output, in the body of the question, together with the code causing the error).
The solution? Call the existing parameterized constructor. E.g. new medStudent("foo", 123).
By the way, if you want inheritance to work okay, and the base-class destructor to be called when deleting an object of a child-class, then you need to make the destructors virtual.

struct output with cout, and function call struct parameters

So, the problem is several errors at compile time.
ReadMovieData(string* title, string* director) cannot convert from movieInfo to string*
DisplayMovieData(string title, string director) cannot convert from movieInfo to string
No operator found which takes a right-hand operand of type 'movieInfo' (or there is no acceptable conversion.
The bottom error happens twice in DisplayMovieData() so I wrote it once for simplicity sake.
The ReadMovieData function should accept a structure pointer reference variable and the DisplayMovieData function should accept a MovieInfo structure variable.
The main function creates an array of 2 MovieInfo struct variables and the other functions should be called on an element of the array.
The code I have finished is below.
#include <stdafx.h>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std;
//prototypes
int ReadMovieData(string* title, string* director);
int DisplayMovieData(string title, string director);
struct movieInfo {
string title, director;
};
int main(){
const int SIZE = 2;
movieInfo movieList[SIZE];
movieInfo movie;
//supposed to assign data to movieList[i] at some point
for (int i = 0; i < SIZE; i++){
ReadMovieData(movie, movie);
DisplayMovieData(movie, movie);
}
return 0;
}
int ReadMovieData(movieInfo &title, movieInfo &director){
movieInfo movie;
//get the movie name
cout << "What is the movie? ";
cin.ignore();
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin.ignore();
cin >> movie.director;
return 0;
}
int DisplayMovieData(movieInfo title, movieInfo director){
cout << "The movie name is: " << title << endl;
cout << "The director of " << title << " is: " << director << endl;
return 0;
}
There are mismatches between your function prototypes and their definitions, as you can see comparing the parameter types in both.
Note that since you defined a structure for the movie info, you can directly pass it to the reading and displaying functions (instead of passing the single structure data member strings).
You may want to read the following compilable code:
#include <iostream>
#include <string>
using namespace std;
struct MovieInfo {
string title;
string director;
};
void ReadMovieData(MovieInfo& movie);
void DisplayMovieData(const MovieInfo& movie);
int main() {
const int SIZE = 2;
MovieInfo movieList[SIZE];
for (int i = 0; i < SIZE; i++) {
ReadMovieData(movieList[i]);
DisplayMovieData(movieList[i]);
}
}
// Since movie is an output parameter in this case, pass by non-const reference.
void ReadMovieData(MovieInfo& movie) {
//get the movie name
cout << "What is the movie? ";
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin >> movie.director;
}
// Since movie is an input parameter in this case, pass by reference to const.
void DisplayMovieData(const MovieInfo& movie) {
cout << "The movie name is: " << movie.title << endl;
cout << "The director of " << movie.title
<< " is: " << movie.director << endl;
}
The errors are pretty explanatory and clear - your function takes string* but you're passing movieInfo - unrelated types can't just magicaly convert one to another.
What you probably want is pass the data members of movieInfo:
ReadMovieData(&movie.title, &movie.director);
It would be better if arguments were not pointers - use references instead. Where you won't be changing the arguments, the references should be to const type.
Even better, why not just pass moveInfo
ReadMovieData(movieInfo& movie);
and let the function deal with the internals of the class? This better encapsulates data and doesn't lead to spaghetti code quite so fast.
Also, the declarations and definitions need to match (otherwise you'd be overloading) - you're using pointers in some places and references/values in others.
Finally, here's how an overload of operator<< might look like:
std::ostream& operator<<(std::ostream& os, const movieInfo& m)
{
return os << "Title: " << m.title << ", Director: " << m.director;
}
Your class movieInfo does not have an overloaded << operator, which is necessary is you want to work with iostream, however, you can pass the strings contained in movieInfo:
int DisplayMovieData(string &title, string &director) { }
Call like:
DisplayMovieData(movie.title, movie.director);
You are declaring the function with this signature
int ReadMovieData(string* title, string* director);
but you're defining it using
int ReadMovieData(movieInfo &title, movieInfo &director) {
// ...
}
These don't match!
The code is totally invalid. I suppose the valid code should look the following way
#include <stdafx.h>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std;
struct movieInfo
{
string title, director;
};
//prototypes
movieInfo ReadMovieData();
void DisplayMovieData( const movieInfo & );
int main()
{
const int SIZE = 2;
movieInfo movieList[SIZE];
//supposed to assign data to movieList[i] at some point
for ( int i = 0; i < SIZE; i++ )
{
movieList[i] = ReadMovieData();
DisplayMovieData( movieList[i] );
}
return 0;
}
movieInfo ReadMovieData()
{
movieInfo movie;
//get the movie name
cout << "What is the movie? ";
cin.ignore();
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin.ignore();
cin >> movie.director;
return movie;
}
void DisplayMovieData( const movieInfo &movie )
{
cout << "The movie name is: " << movie.title << endl;
cout << "The director of " << movie.title << " is: " << movie.director << endl;
}

Trying to make string array passed through methods 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.