Semi-answer To explain the bad habits:
#include <string>
#include <iostream>
#include <vector>
//using namespace std; often injects subtle bugs. Use with caution
// read more here:
// http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
struct student
{
std::string name; // explicit namespacing reduces possibility of unwanted collisions
int age;
float marks;
//added constructor in place of initialization function.
student(std::string name, int age, float marks):name(name), age(age), marks(marks)
{
}
};
int main()
{
int totalStudents = 1;
std::string name;
int age;
float marks;
while (!(std::cin >> totalStudents)) // testing input for success
// Needed extra brackets caught by M.M
// teach me to not test even a throw-away example
{
std::cout << "must... have... good... input..." << std::endl;
cin.clear(); // clear the error and get rid of any other garbage the user may have input.
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
//student *stud[totalStudents]; illegal in C++
std::vector<student *> stud(totalStudents); // using dynamic array instead
for (int i = 0; i < totalStudents; )// i++ removed
{
if (std::cin >> name >> age >> marks) //testing input
{
stud[i] = new student(name, age, marks); // using constructor
i++; // and put here. Only increment if input is valid.
}
else
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
std::cout << stud[0]->name;
for (student * stu: stud) // cleaning up allocated memory
{
delete stu;
}
return 0;
}
One of the beauties of C++ is you rarely need to self-manage memory. In fact there are huge advantages in not doing it above and beyond not having to clean up after yourself.
#include <string>
#include <iostream>
#include <vector>
struct student
{
std::string name;
int age;
float marks;
student(std::string name, int age, float marks):name(name), age(age), marks(marks)
{
}
};
int main()
{
std::string name;
int age;
float marks;
std::vector<student> stud; // look ma! No pointer!
while (std::cin >> name >> age >> marks) //exits loop on bad input
{
stud.emplace_back(name, age, marks); // building directly in vector
// vector will size itself as needed.
}
std::cout << stud[0].name;
return 0;
}
One more caveat: >>
is whiespace delimited. That means it stops when it finds whitespace (space, tab, end of line...) so a name of "John Jacob Jingleheimer-Shmidt" will go into name as "John". >>
will then attempt to interpret "Jacob" as age
, and that will not go so well.