Crashing after reading with cin - c++

For some reason the program always crashes the second time I main calls inputHolding() and tries to get the call number (the call number is entered and then it crashes). How do I fix this crash? Here is a picture of the call stack and where it is crashing in my code: http://i.imgur.com/zWJ17NC.png
#include <iostream>
#include "LibraryDrv.h"
using namespace std;
int main() {
Holding *hptr[5];
for (int i = 0; i < 5; i++) {
hptr[i] = inputHolding();
}
for (int i = 0; i < 5; i++) {
hptr[i]->print();
}
return 0;
}
Holding* inputHolding() {
char selection;
char title[50];
int callNumber = 0;
char author[50];
char performer[50];
char format;
cout << "Enter B for book, R for recording: ";
cin >> selection;
if (selection == 'B') {
cout << "Enter book title: ";
cin >> title;
cout << "Enter book author: ";
cin >> author;
cout << "Enter call number: ";
cin >> callNumber;
Book* aBook = new Book(title, callNumber, author);
return aBook;
}
else if (selection == 'R') {
cout << "Enter recording title: ";
cin >> title;
cout << "Enter performer: ";
cin >> performer;
cout << "Enter format: (M)P3, (W)AV, (A)IFF: ";
cin >> format;
cout << "Enter call number: ";
cin >> callNumber;
Recording* aRecording = new Recording(title, callNumber, performer, format);
return aRecording;
}
else {
cout << "Incorrect selection" << endl;
return nullptr;
}
}

Related

What should I do to get out of the called function and continue with the other function?

I have created a struct questions with the element testQuestion, answerQuestion and point. I also created a void function which is connected to the elements of the struct. When I call the function and input the question, the program does not continue to the other element which is the answer but turns back to input username and password.
Why does this happen?
struct professor
{
string username;
string password;
};
professor professorData;
struct question
{
char testQuestion[50];
char answerQuestion[50];
int pointQuestion;
};
question questionData;
void readProfessor(professor &professorData)
{
cout << "Enter the professor username: ";
cin >> professorData.username;
cout << "Enter the professor password: ";
cin >> professorData.password;
cout << endl;
}
void readQuestion(question &questionData)
{
cout << "Enter the question: " << endl;
cin >> questionData.testQuestion;
cout << "Enter the answers: " << endl;
cin >> questionData.answerQuestion;
}
void professorMenu()
{
string pUsername;
string pPassword;
cout << "Enter professor username: ";
cin >> pUsername;
cout << "Enter professor password: ";
cin >> pPassword;
if ((pUsername.compare(professorData.password) == 0) && (pPassword.compare(professorData.password) == 0))
{
readQuestion(questionData);
}
}
Calling from here
adminMenu()
{
int adminUsername = 1234;
int inputAdminUsername;
char adminPassword[6] = "admin";
char inputAdminPassword[6];
int a;
string inputStudent[20];
string inputProfessor[20];
cout << "Enter admin username: ";
cin >> inputAdminUsername;
cout << "Enter admin password: ";
cin >> inputAdminPassword;
if (inputAdminUsername == adminUsername && strcmp(adminPassword, inputAdminPassword) == 0)
{
cout << "Successful login." << endl;
do
{
cout << "Press 1 to add professor" << endl;
cout << "Press 2 to add student" << endl;
cout << "Press 3 to go back to main menu" << endl;
cin >> a;
if (a == 1)
{
readProfessor(professorData);
}
else if (a == 2)
{
readStudent(studentData);
}
else if (a == 3)
mainMenu();
} while (a != 3);
}
}

can't extract data from a structure array c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
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.
Closed 5 years ago.
Improve this question
the program works fine and executes all options, but in the 3rd and 4th option, in 3rd when i search for a student the program doesn't go beyond the data input part while in 4th when i search for data and print it, it gives garbage values in the variables with int datatype while doesn't display string or char type variables. any help would be much appreciated. EDIT: sorry for the inconvenience, I've now separated the functions form the main code. Hope its its more understandable now.
#include<iostream>
#include<string>
using namespace std;
int ncr;
int me,n=0,u,y,l;
char opt1,opt2,opt3,opt4;
struct student
{
string Name;
int DoB;
int Age;
string Address;
string Course[5];
char grade[5];
};
void add();
void remove();
void update();
void search();
int main()
{ int opt;
student s[n];
while(1)
{
cout<<" select what you want to do \n\n 1. Add new record \n2. Remove record\n3. Update Record\n4. Search for particular student\n" ;
cin>>opt;
if(opt==1)
{add();}
else if(opt==2)
{remove();}
else if(opt==3)
{update();}
else if(opt==4)
{search();}
}
}
.
void add(){
n++;
student s[n];
do
{ cout<<"enter name of student ";
cin>>s[n-1].Name;
cout<<"enter DoB of student ";
cin>>s[n-1].DoB;
cout<<"enter age of student ";
cin>>s[n-1].Age;
cout<<"enter address of student ";
cin>>s[n-1].Address;
cout<<"enter courses and grades (max 5) \n";
for(int x=0;x<5;x++){
cout<<"course:";
cin>>s[n-1].Course[x];
cout<<"grade:";
cin>> s[n-1].grade[x];}
cout<<"Roll No. : "<<n<<"\nName :"<<s[n-1].Name<<"\nDoB :"<<s[n-1].DoB<<"\nAge :"<<s[n-1].Age<<"\nAddress :"<<s[n-1].Address;
for(int x=0;x<5;x++){
cout<<"\n"<<s[n-1].Course[x];
cout<<" grade : "<< s[n-1].grade[x]<<"\n";}
cout<<"repeat for another student 'y' or 'n' ?";
cin>>opt1;
}
while(opt1=='y'|| opt1=='Y');
}
.
void remove(){student s[n];
do
{
cout<<"enter student roll no to remove data";cin>>l;
for(int i=l;i<n;i++)
{ s[l-1].Name=s[l].Name;
s[l-1].DoB= s[l].DoB;
s[l-1].Age=s[l].Age;
s[l-1].Address=s[l].Address;
for(int j=0;j<5;j++){
s[l-1].Course[j]=s[l].Course[j];
s[l-1].grade[j]=s[l].grade[j];}
}
cout<<"Record Removed\n";
n--;
cout<<"repeat ? 'y' or 'n' ";
cin>>opt2;
}
while(opt2 == 'y' || opt2 == 'Y');}
.
void update(){
student s[n];
do
{
cout<<"enter the roll no of student you want to update data";
cin>>u;
cout<<"Roll No. : "<<u;
cout<<"\nName : ";
cout<<s[u-1].Name;
cout<<"\nDoB : ";
cout<<s[u-1].DoB;
cout<<"\nAge : ";
cout<<s[u-1].Age;
cout<<"\nAddress :";
cout<<s[u-1].Address;
cout<<"\nCourses and Grades\n";
for(int r=0;r<5;r++)
{
cout<<s[u-1].Course[r];
cout<<"\t"<< s[u-1].grade[r]<<endl;
}
cout<<"enter name of student ";
cin>>s[u-1].Name;
cout<<"enter DoB of student ";
cin>>s[u-1].DoB;
cout<<"enter age of student ";
cin>>s[u-1].Age;
cout<<"enter address of student ";
cin>>s[u-1].Address;
cout<<"enter courses and grades (max 5) \n";
for(int x=0;x<5;x++){
cout<<"course:";
cin>>s[u-1].Course[x];
cout<<"grade:";
cin>> s[u-1].grade[x];}
cout<<"Roll No. : "<<u;
cout<<"\nName : ";
cout<<s[u-1].Name;
cout<<"\nDoB : ";
cout<<s[u-1].DoB;
cout<<"\nAge : ";
cout<<s[u-1].Age;
cout<<"\nAddress :";
cout<<s[u-1].Address;
cout<<"\nCourses and Grades\n";
for(int r=0;r<5;r++)
{ cout<<s[u-1].Course[r];
cout<<"\t"<< s[u-1].grade[r]<<endl; }
cout<<"repeat ? 'y' or 'n' ";
cin>>opt3;
}
while(opt3 == 'y' || opt3 == 'Y');
}
.
void search(){
student s[n];
do
{
cout<<"enter the roll no of student you want to search data of";
cin>>y;
cout<<"Roll No. : "<<n<<"\nName :"<<s[y-1].Name<<"\nDoB :"<<s[y-1].DoB<<"\nAge :"<<s[y-1].Age<<"\nAddress :"<<s[y-1].Address<<"\nCourses and Grades\n";
for(int r=0;r<5;r++)
{
cout<<s[y-1].Course[r];
cout<<"\t"<< s[y-1].grade[r]<<endl;
}
cout<<"repeat ? 'y' or 'n' ";
cin>>opt4;
}
while(opt4 == 'y' || opt4 == 'Y');}
This should look a bit more like a code intended for humans to read :)
#include<iostream>
#include<string>
using namespace std;
int ncr;
int me,n=0,u,y,l;
char opt1,opt2,opt3,opt4;
struct student
{
string Name;
int DoB;
int Age;
string Address;
string Course[5];
char grade[5];
};
void add();
void remove();
void update();
void search();
int main()
{
int opt;
student s[n];
while(1)
{
cout << " select what you want to do \n\n 1. Add new record \n2. Remove record\n3. Update Record\n4. Search for particular student\n" ;
cin >> opt;
if(opt==1)
{
add();
}
else if(opt==2)
{
remove();
}
else if(opt==3)
{
update();
}
else if(opt==4)
{
search();
}
}
}
void add()
{
n++;
student s[n];
do
{
cout << "enter name of student ";
cin >> s[n-1].Name;
cout << "enter DoB of student ";
cin >> s[n-1].DoB;
cout << "enter age of student ";
cin >> s[n-1].Age;
cout << "enter address of student ";
cin >> s[n-1].Address;
cout << "enter courses and grades (max 5) \n";
for(int x=0;x<5;x++)
{
cout<<"course:";
cin>>s[n-1].Course[x];
cout<<"grade:";
cin>> s[n-1].grade[x];
}
cout << "Roll No. : " << n << "\nName :" << s[n-1].Name << "\nDoB :" << s[n-1].DoB << "\nAge :" << s[n-1].Age << "\nAddress :" << s[n-1].Address;
for( int x = 0; x < 5; x++ )
{
cout << "\n"<<s[n-1].Course[x];
cout << " grade : "<< s[n-1].grade[x]<<"\n";}
cout << "repeat for another student 'y' or 'n' ?";
cin >> opt1;
}
while(opt1=='y'|| opt1=='Y');
}
void remove()
{
student s[n];
do
{
cout << "enter student roll no to remove data";
cin >> l;
for( int i=l; i < n; i++ )
{
s[l-1].Name=s[l].Name;
s[l-1].DoB= s[l].DoB;
s[l-1].Age=s[l].Age;
s[l-1].Address=s[l].Address;
for(int j=0;j<5;j++)
{
s[l-1].Course[j]=s[l].Course[j];
s[l-1].grade[j]=s[l].grade[j];
}
}
cout<<"Record Removed\n";
n--;
cout << "repeat ? 'y' or 'n' ";
cin >> opt2;
}
while(opt2 == 'y' || opt2 == 'Y');
}
void update()
{
student s[n];
do
{
cout << "enter the roll no of student you want to update data";
cin >> u;
cout << "Roll No. : " << u;
cout << "\nName : ";
cout << s[u-1].Name;
cout << "\nDoB : ";
cout << s[u-1].DoB;
cout << "\nAge : ";
cout << s[u-1].Age;
cout << "\nAddress :";
cout << s[u-1].Address;
cout << "\nCourses and Grades\n";
for( int r=0; r < 5; r++ )
{
cout << s[u-1].Course[r];
cout << "\t"<< s[u-1].grade[r] << endl;
}
cout << "enter name of student ";
cin >> s[u-1].Name;
cout << "enter DoB of student ";
cin >> s[u-1].DoB;
cout << "enter age of student ";
cin >> s[u-1].Age;
cout << "enter address of student ";
cin >> s[u-1].Address;
cout << "enter courses and grades (max 5) \n";
for(int x=0; x < 5; x++ )
{
cout<<"course:";
cin>>s[u-1].Course[x];
cout<<"grade:";
cin>> s[u-1].grade[x];
}
cout << "Roll No. : " << u;
cout << "\nName : ";
cout << s[u-1].Name;
cout << "\nDoB : ";
cout << s[u-1].DoB;
cout << "\nAge : ";
cout << s[u-1].Age;
cout << "\nAddress :";
cout << s[u-1].Address;
cout << "\nCourses and Grades\n";
for( int r = 0; r < 5; r++)
{
cout << s[u-1].Course[r];
cout << "\t"<< s[u-1].grade[r]<<endl;
}
cout << "repeat ? 'y' or 'n' ";
cin >> opt3;
}
while(opt3 == 'y' || opt3 == 'Y');
}
void search()
{
student s[n];
do
{
cout << "enter the roll no of student you want to search data of";
cin >> y;
cout << "Roll No. : " << n << "\nName :" << s[y-1].Name << "\nDoB :" << s[y-1].DoB << "\nAge :" << s[y-1].Age << "\nAddress :" << s[y-1].Address << "\nCourses and Grades\n";
for( int r=0; r < 5; r++ )
{
cout << s[y-1].Course[r];
cout << "\t" << s[y-1].grade[r]<<endl;
}
cout << "repeat ? 'y' or 'n' ";
cin >> opt4;
}
while( opt4 == 'y' || opt4 == 'Y' );
}
The problem you're having is with the scope of your programme.
In the main() function you declare an array, which presumably should be holding all the records. However for every option (function add/remove/update/search) you declare a new one. These arrays are local to those functions and are being "forgotten" after the function is finished.
In order to fix that, you have to pass the original array (the one from main()) to those functions.
The next problem, which is more severe is the fact, that you can't change the size of an array in the runtime! The elements you were accessing in the 3rd option were some random bytes in the memory and this can cause a lot of trouble.
Either create an array with e.g. 100 fields ( student s[100]; ), or even better try using std::vector, which can size you can adjust according to the number of records.
Third thing, remember that formatting code is extremely important. Hopefully it was just a copy-paste problem that made your code look unreadable, but if it's not the case then try to change. Well formatted code is easier to understand and will make it easier for you to debug it.

My program is not asking for input

I am writing a program and it is a long program and I have just started. I just tested it for running, Please tell me why it is not having user input:
#include <iostream>
using namespace std;
struct courses{
int CLO1, CLO2, CLO3, CLO4, CLO5;
int tcounter;
};
int main(){
cin.clear();
courses C1;
C1.CLO1;
C1.CLO2;
C1.CLO3;
int counter = 0;
char name;
cout << "Enter your Name: ";
cin >> name;
cout << "For C1, we have three CLOs that CLO1,CLO2 and CLO3. CLO1 and CLO3 are linked to PLO1 and CLO2 is linked to PLO2 " << endl;
cout << "Enter your marks in CLO1 for C1:(Out of 10) ";
cin >> C1.CLO1;
if (C1.CLO1 >= 5){
counter++;
}
cout << "Enter your marks in CLO2 for C1:(Out of 10) ";
cin >> C1.CLO2;
if (C1.CLO2 >= 5){
counter++;
}
cout << "Enter your marks in CLO3 for C1:(Out of 10) ";
cin >> C1.CLO3;
if (C1.CLO3 >= 5){
counter++;
}
cout << counter;
return 0;
}
As per me the program is fine.
Three things you need to change:
variable type of name from char to string
C1.CLO1;C1.CLO2;C1.CLO3; remove these from your code it doesn't make any sense.
Print the values and check :P

cross initialization error in while loop (c++ program)

I am doing a lot of things wrong here. Plz help.
#include <iostream>
#include <fstream>
using namespace std;
class student {
int rno;
char name[15];
float marks;
public:
void getdata()
{
cout << "\nEnter Roll No. : ";
cin >> rno;
cout << "\nEnter Name : ";
cin >> name;
cout << "\nEnter Marks : ";
cin >> marks;
};
void writedata()
{
fstream input;
input.open("stu.dat", ios::out | ios::app);
input.write((char*)this, sizeof(student));
input.close();
};
void readdata()
{
int temp;
cout << "\nEnter roll no: ";
cin >> temp;
fstream output;
output.open("stu.dat", ios::in);
output.seekg(0, ios::beg);
while (output.read((char*)this, sizeof(student))) {
if (rno == temp) {
cout << "\nRoll no. : " << rno
<< "\nName : " << name
<< "\nMarks : " << marks;
}
else {
cout << "\nWrong Roll no entered";
};
};
};
};
int main()
{
student s[25];
student* st;
char ans = 'y', ans2 = 'y', ans3 = 'y';
int o, i = 0, j = 0;
do {
cout << "\nEnter your choice\n1.Write\n2.Read";
cin >> o;
switch (o) {
case 1:
while (ans2 == 'y' || ans2 == 'Y') {
s[i].getdata();
s[i].writedata();
cout << "\nDo you want to continue?";
cin >> ans2;
i++;
};
break;
case 2:
while (ans3 == 'y' || ans3 == 'Y') {
st->readdata();
cout << "\nDo you want to continue?";
cin >> ans3;
j++;
};
break;
};
} while (ans == 'y' || ans == 'Y');
return 0;
}
All seems well until line 82:
st->readdata();
where the variable st is not initialised but used.

Do-while loop only executing when it feels like it in C++?

So I have this do-while loop which is supposed to repeat asking if you want to enter info for a student if you do press y and enter info via an input() function the data is then stored in a vector. If you press q, the program is supposed to print the info contained in the vector and exit the loop.
For some reason the loop fully executes for the first and second student you enter. Then instead of repeating the loop asking if you want to enter a third student it seems to just execute the input() function. It doesn't ask you 'Enter y to continue or q to quit' and any student info you enter here does not seemed to be stored. It does this intermittently changing between executing the full loop and just the input() function. I'm wondering if anyone knows why this is happening and what I can do to fix it.
Cheers
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int NO_OF_TEST = 4;
struct studentType
{
string studentID;
string firstName;
string lastName;
string subjectName;
string courseGrade;
int arrayMarks[4];
double avgMarks;
};
studentType input();
double calculate_avg(int marks[],int NO_OF_TEST); // returns the average mark
string calculate_grade (double avgMark); // returns the grade
void main()
{
unsigned int n=0; // no. of student
vector<studentType> vec; // vector to store student info
studentType s;
char response;
do
{
cout << "\nEnter y to continue or q to quit... ";
cin >> response;
if (response == 'y')
{
n++;
for(size_t i=0; i<n; ++i)
{
s = input();
vec.push_back(s);
}
}
else if (response == 'q')
{
for (unsigned int y=0; y<n; y++)
{
cout << "\nFirst name: " << vec[y].firstName;
cout << "\nLast name: " << vec[y].lastName;
cout << "\nStudent ID: " << vec[y].studentID;
cout << "\nSubject name: " << vec[y].subjectName;
cout << "\nAverage mark: " << vec[y].avgMarks;
cout << "\nCourse grade: " << vec[y].courseGrade << endl << endl;
}
}
}
while(response!='q');
}
studentType input()
{
studentType newStudent;
cout << "\nPlease enter student information:\n";
cout << "\nFirst Name: ";
cin >> newStudent.firstName;
cout << "\nLast Name: ";
cin >> newStudent.lastName;
cout << "\nStudent ID: ";
cin >> newStudent.studentID;
cout << "\nSubject Name: ";
cin >> newStudent.subjectName;
for (int x=0; x<NO_OF_TEST; x++)
{ cout << "\nTest " << x+1 << " mark: ";
cin >> newStudent.arrayMarks[x];
}
newStudent.avgMarks = calculate_avg(newStudent.arrayMarks,NO_OF_TEST );
newStudent.courseGrade = calculate_grade (newStudent.avgMarks);
return newStudent;
}
double calculate_avg(int marks[], int NO_OF_TEST)
{
double sum=0;
for( int i=0; i<NO_OF_TEST; i++)
{
sum = sum+ marks[i];
}
return sum/NO_OF_TEST;
}
string calculate_grade (double avgMark)
{
string grade= "";
if (avgMark<50)
{
grade = "Fail";
}
else if (avgMark<65)
{
grade = "Pass";
}
else if (avgMark<75)
{
grade = "Credit";
}
else if (avgMark<85)
{
grade = "Distinction";
}
else
{
grade = "High Distinction";
}
return grade;
}
I think this code does it:
n++;
for(size_t i=0; i<n; ++i)
{
s = input();
vec.push_back(s);
}
It asks you for two students the second time, for three student the third time, etc.
So, make it
vec.push_back(input());