Unable to print out information - c++

I am writing a program which stores students' information (ID, name, major, cpa and assessment). When I compile it, there is no errors and it runs smoothly until outputting the result after inputting the information successfully. When I debug, I'm sure that the information has been successfully inserted and the error is in the display function. I really need your help to figure out what the error is.
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
using namespace std;
class Student
{
public:
string student_id;
string name;
string major;
float gpa;
char assessment;
Student()
{
student_id = "";
name = "";
major = "";
gpa = 0.0;
assessment = 'F';
}
void addinfo(string id, string student_name, string student_major, float student_gpa)
{
this->student_id = id;
this->name = student_name;
this->major = student_major;
this->gpa = student_gpa;
}
char assessstudent()
{
if (this->gpa >= 8.0)
return 'A';
if (this->gpa < 8.0 && this->gpa >= 6.0)
return 'B';
if (this->gpa < 6.0 && this->gpa >= 4.0)
return 'C';
if (this->gpa < 4.0 && this->gpa >= 2.0)
return 'D';
if (this->gpa < 2.0)
return 'F';
}
};
void swap(float* a, float* b)
{
float temp;
temp = *a;
*a = *b;
*b = temp;
}
void sortwithgrade(Student* array, int r, int l)
{
float temp = array[r].gpa;
int m = (r + l) / 2;
int i = l+1;
int j = r ;
if (r > l)
{
while (1)
{
while (array[++i].gpa <= temp)
;
while (array[--j].gpa >= temp)
;
if (i >= j)
break;
swap(array[i], array[j]);
}
swap(array[i], array[r]);
sortwithgrade(array, l, m - 1);
sortwithgrade(array, m + 1, r);
}
}
void display(Student* array, int max)
{
int i = 0;
printf("%-20s%-20s%-20s%-20s%-20s\n", "Student ID", "Student name", "Student Major", "Student gpa", "Student Assess");
while (i != max)
{
printf("%-20s%-20s%-20s%-20.2f%c\n", array[i].student_id, array[i].name, array[i].major, array[i].gpa, array[i].assessment);
i++;
}
}
int main()
{
Student list[10];
cout << "How many students do you want to add?\n";
int max;
cin >> max;
getchar();
int i = 0;
for (i = 0; i < max; i++)
{
cout << "Student number " << i << endl;
cout << "ID: ";
string stdid;
getline(cin, stdid);
cout << "Name: ";
string stdname;
getline(cin, stdname);
cout << "Major: ";
string stdmajor;
getline(cin, stdmajor);
cout << "GPA: ";
float gpa;
cin >> gpa;
getchar();
list[i].addinfo(stdid, stdname, stdmajor, gpa);
char stdassess = list[i].assessstudent();
list[i].assessment = stdassess;
}
sortwithgrade(list, 0, max - 1);
display(list, max);
return 0;
}

Related

How do I stop the debugger from skipping my functions?

I am trying to calculate students grades from a file. When entering the if statement the debugger skips all my functions and ends the program. I think it has something to do with the file not being inputted well.
int main()
{
string temp, out = "";
ifstream RF("TestAnswers(5).txt");
while (getline(RF, temp))
{
out += temp;
}
GradeCalc gCalc;
gCalc.gradeAspects(out);
gCalc.gradeCalculation();
gCalc.grade();
}
class GradeCalc
{
private:
#define DELIM ','
struct GradeAspects
{
string studentN;
string answers;
string firstname, lastname;
double scores;
int rsize;
string percent;
string readFile; // int read;
};
vector<GradeAspects> read;
GradeAspects readFile[25];
public:
void gradeAspects(string filename);
void gradeCalculation();
void grade();
};
void GradeCalc::gradeAspects(string filename)
{
ifstream input;
string line;
int rnum = 0;
char delim;
int rsize;
input.open(filename);
if (input)
{
while (!input.eof())
{
getline(input, line);
delim = line.find(DELIM);
readFile[rnum].studentN = line.substr(0, delim);
line = line.substr(delim + 1, line.length() - 1);
delim = line.find(DELIM); // moving on to firstname by finding delim.
readFile[rnum].firstname = line.substr(0, delim);
line = line.substr(delim + 1, line.length() - 1);
delim = line.find(DELIM); // moving on to lastname by finding delim.
readFile[rnum].lastname = line.substr(0, delim); // last name
line = line.substr(delim + 1, line.length() - 1);
delim = line.find(DELIM);
readFile[rnum].answers = line; // line = line.substr(delim + 1, line.length() - 1);
rnum++;
}
}
rsize = rnum;
}
void GradeCalc::gradeCalculation()
{ // once done with reads move to calculations of how many answers were right etc.
int rnum = 0;
int rsize = 0;
string answers = readFile[0].answers;
int aSize = answers.size();
for (int i = 0; i < rsize; i++)
{
int score = 0;
for (int t = 0; t < aSize; t++)
{
if (answers[t] == readFile[i].answers[i])
score++;
{
answers[i] = score;
}
}
}
}
void GradeCalc::grade()
{
string line;
int rnum = 0;
int aSize = line.length();
int choices{};
int rsize = 0;
int grade{};
for (int i = 0; i < rsize; i++)
{
int score = 0;
readFile[i].answers = choices;
readFile[i].percent = grade;
readFile[i].percent = (choices / aSize * 100);
if (grade >= 90)
readFile[rnum].firstname = "A";
else if (grade > 80 && grade < 90)
readFile[rnum].firstname = "B";
else if (grade > 70 && grade < 80)
readFile[rnum].firstname = "C";
else if (grade < 70)
readFile[rnum].firstname = "F";
cout << "student" << readFile[rnum].firstname << " " << readFile[rnum].lastname << " had "
<< readFile[i].answers << " out of " << aSize << "and has a grade of" << grade << endl;
}
}

I am trying to add large numbers using arrays without using bigint or anything like that. C++

I am trying to add large numbers using arrays without using bigint or anything like that. I can get my program to add the two arrays. However, I need to take the addition of the arrays and output the correct answer like a regular number. I cannot seem to make an algorithm to take the sum of my arrays and ouptut the answer. Does anybody have any tips or suggestions?
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>
#include <iterator>
using namespace std;
const int DIGITS = 20;
void readNum(int list[], int& length, string input1);
void reverseArray(int arr[], int start, int end);
void sumNum(int list1[], int numOfElementsList1,
int list2[], int numOfElementsList2);
int main()
{
// Write your main here
string input1;
string input2;
int list[DIGITS];
int list2[DIGITS];
int total[DIGITS];
int input1Length;
int input2Length;
cout << "Please enter your 1st number: " << endl;
cin >> input1;
cout << "Please enter your 2nd number: " << endl;
cin >> input2;
input1Length = input1.length();
input2Length = input2.length();
readNum(list, input1Length, input1);
readNum(list2, input2Length, input2);
reverseArray(list, 0, input1Length);
reverseArray(list2, 0, input2Length);
sumNum(list, input1Length, list2, input2Length);
}
void readNum(int list[], int& length, string input1)
{
int array[DIGITS];
for (int i = 0; i < length; i++)
{
array[i] = input1[i] - '0';
list[i] = array[i];
}
}
void reverseArray(int arr[], int start, int length)
{
int end;
end = length - 1;
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
void sumNum(int list1[], int numOfElementsList1,
int list2[], int numOfElementsList2)
{
int length;
int sum = 0;
int carry = 0;
int total[DIGITS];
if (numOfElementsList1 > numOfElementsList2)
{
length = numOfElementsList1;
}
else
{
length = numOfElementsList2;
}
for (int i = 0; i < length; i++)
{
sum = list1[i] + list2[i] + carry;
if (sum >= 10)
{
sum = sum % 10;
carry = 1;
}
else
{
carry = 0;
}
total[i] = sum;
cout << total[i];
}
}
Strings are arrays of characters, you could just use them as-is. The advantage being... they're just strings, and you can output them as a string just as easily. Not a new technique, it's called a binary coded decimal which in this case is a zoned BCD (where the zone is 0x30 in ASCII, or zone 0xF0 in EBCDIC).
#include <iostream>
#include <string>
#include <stdexcept>
using std::string;
using std::cout;
using std::cin;
using std::runtime_error;
static string sumNum(string, string);
int main() {
string input1;
string input2;
cout << "Please enter your 1st number: ";
cin >> input1;
cout << "Please enter your 2nd number: ";
cin >> input2;
auto sum = sumNum(input1, input2);
cout << "Sum is: " << sum << "\n";
}
string sumNum(string a, string b) {
//a = string(a.rbegin(), a.rend());
//b = string(b.rbegin(), b.rend());
string sum;
auto digit = [carry = 0](int value) mutable {
value += carry;
if (value > 9) {
carry = 1;
value -= 10;
} else {
carry = 0;
}
return static_cast<char>(value + '0');
};
auto num = [](char c) {
if (c < '0' || c > '9') {
throw runtime_error("not a digit");
}
return c - '0';
};
auto aa = a.rbegin();
auto bb = b.rbegin();
while(aa != a.rend() && bb != b.rend()) {
sum.push_back(digit((num(*aa)) + (num(*bb))));
++aa;
++bb;
}
while (aa != a.rend()) {
sum.push_back(digit(num(*aa)));
++aa;
}
while (bb != b.rend()) {
sum.push_back(digit(num(*bb)));
++bb;
}
char last = digit(0);
if (last != '0')
sum.push_back(last);
return string(sum.rbegin(), sum.rend());
}

Bubble array sort in C++ implementation

I'm trying to get this code to sort names but it doesn't seem to work for me. What could be wrong? I have a class named Student and want to pass the names and sort them in ascending order. So what I am trying to do is pass the 4 object firstname onto the the sort_list function and sort them in ascending order and display them afterwards. However when I run the code it shows me the same order I had and the sort function didn't seem to have done anything. See if you guys can help me out here.
#include <iostream>
#include<string>
using namespace std;
//***************************************************************************
//STUDENT CLASS
//***************************************************************************
class Student
{
private:
string firstname;
string lastname;
string studentID;
string phoneNumber;
double gpa;
public:
Student();
Student(const string&, const string&, const string&, const string&, const double&);
string getfirstName() const;
string getlastName() const;
string getstudentId() const;
string getphoneNumber() const;
double getGPA() const;
void setfirstName(string&);
void setlastName(string&);
void setstudentId(string&);
void setphoneNumber(string&);
void setGAP(double&);
};
Student::Student()
{
firstname = " ";
lastname = " ";
studentID = " ";
phoneNumber = " ";
gpa = 0;
}
Student::Student(const string&a, const string&b, const string&c, const string&d, const double&e)
{
firstname = a;
lastname = b;
studentID = c;
phoneNumber = d;
gpa = e;
}
string Student::getfirstName()const
{
return firstname;
}
string Student::getlastName()const
{
return lastname;
}
string Student::getstudentId() const
{
return studentID;
}
string Student::getphoneNumber() const
{
return phoneNumber;
}
double Student::getGPA() const
{
return gpa;
}
void Student::setfirstName(string&u)
{
firstname = u;
}
void Student::setlastName(string&v)
{
lastname = v;
}
void Student::setstudentId(string&x)
{
studentID = x;
}
void Student::setphoneNumber(string&y)
{
phoneNumber = y;
}
void Student::setGAP(double&z)
{
gpa = z;
}
//***************************************************************************
//COURSE CLASS
//***************************************************************************
class Course :public Student
{
private:
string code;
int section;
int capacity;
int numStudents;
Student *list;
public:
Course();
Course(string, int, int);
~Course();
string getCourseCode();
int getSection();
int getCapacity();
int getNumStudents();
void setCourseCode(string);
void setSection(int);
void add(const Student&);
void display();
void display(const string, const int);
void remove(const string m, const int n);
void sort_list();
};
Course::Course()
{
code = "CMPT1020";
section = 1;
capacity = 35;
numStudents = 0;
list = new Student[35];
}
Course::Course(string a, int b, int c)
{
code = a;
section = b;
capacity = c;
numStudents = 0;
list = new Student[c];
}
Course::~Course()
{
delete[] list;
list = nullptr;
}
string Course::getCourseCode()
{
return code;
}
int Course::getSection()
{
return section;
}
int Course::getCapacity()
{
return capacity;
}
int Course::getNumStudents()
{
return numStudents;
}
void Course::setCourseCode(string a)
{
code = a;
}
void Course::setSection(int b)
{
section = b;
}
void Course::add(const Student& s)
{
if (numStudents == capacity)
{
cout << "Course is full" << endl;
return;
}
list[numStudents] = s;
numStudents++;
int i = numStudents - 2;
while (i >= 0 && (s.getGPA() > list[i].getGPA()))
{
list[i + 1] = list[i];
i--;
}
list[i + 1] = s;
}
void Course::display()
{
for (int i = 0; i < numStudents; i++)
{
cout<<list[i].getfirstName() <<" "<< list[i].getlastName() <<" "<< list[i].getstudentId() <<" "<< list[i].getphoneNumber() <<" "<< list[i].getGPA() << endl;
}
}
void Course::display(const string x, const int y)
{
if (y == 1)
{
for (int i = 0; i < numStudents; i++)
{
if (list[i].getfirstName() == x)
{
cout << list[i].getfirstName() << " " << list[i].getlastName() << " " << list[i].getstudentId() << " " << list[i].getphoneNumber() << " " << list[i].getGPA() << endl;
}
}
}
if (y == 2)
{
for (int i = 0; i < numStudents; i++)
{
if (list[i].getlastName() == x)
{
cout << list[i].getfirstName() << " " << list[i].getlastName() << " " << list[i].getstudentId() << " " << list[i].getphoneNumber() << " " << list[i].getGPA() << endl;
}
}
}
if (y == 3)
{
for (int i = 0; i < numStudents; i++)
{
if (list[i].getstudentId() == x)
{
cout << list[i].getfirstName() << " " << list[i].getlastName() << " " << list[i].getstudentId() << " " << list[i].getphoneNumber() << " " << list[i].getGPA() << endl;
}
}
}
if (y == 4)
{
for (int i = 0; i < numStudents; i++)
{
if (list[i].getphoneNumber() == x)
{
cout << list[i].getfirstName() << " " << list[i].getlastName() << " " << list[i].getstudentId() << " " << list[i].getphoneNumber() << " " << list[i].getGPA() << endl;
}
}
}
}
void Course::remove(const string a, const int b)
{
if (b == 1)
{
for (int i = 0; i < numStudents; i++)
{
if (list[i].getfirstName() == a)
{
for (int j = i; j < numStudents; j++)
{
list[j] = list[j + 1];
}
numStudents--;
}
}
}
if (b == 2)
{
for (int i = 0; i < numStudents; i++)
{
if (list[i].getlastName() == a)
{
for (int j = i; j < numStudents; j++)
{
list[j] = list[j + 1];
}
numStudents--;
}
}
}
if (b == 3)
{
for (int i = 0; i < numStudents; i++)
{
if (list[i].getstudentId() == a)
{
for (int j = i; j < numStudents; j++)
{
list[j] = list[j + 1];
}
numStudents--;
}
}
}
if (b == 4)
{
for (int i = 0; i < numStudents; i++)
{
if (list[i].getphoneNumber() == a)
{
for (int j = i; j < numStudents; j++)
{
list[j] = list[j + 1];
}
numStudents--;
}
}
}
}
void Course::sort_list()
{
string temp;
for (int i = 0; i < numStudents; i++)
{
for (int j = 0; j < numStudents-1; j++)
{
if(list[j].getfirstName() >list[j+1].getfirstName())
{
temp = list[j].getfirstName();
list[j].getfirstName() = list[j+1].getfirstName();
list[j+1].getfirstName() = temp;
}
}
}
}
int main()
{
Student a("Kevin", "Chen", "300215915", "7788408028", 2);
Student b("Mickey", "Mouse", "12345678", "2222222222", 2.5);
Student c("Donald", "Duck", "24681012", "3333333333", 3.0);
Student d("Goofy", "Dog", "3579111315", "5555555555", 3.5);
Course x;
x.add(a);
x.add(b);
x.add(c);
x.add(d);
x.display();
cout << endl;
x.sort_list();
x.display();
/*cout << " " << endl;
x.remove("kevin", 1);
x.remove("Chen", 2);
x.remove("300215915", 3);
x.remove("7788408028", 4);
x.display();
cout << endl;
x.display("kevin", 1);
x.display("Mouse", 2);
x.display("24681012", 3);
x.display("5555555555", 4);*/
system("pause");
return 0;
}
It is true that your sorting code doesn't do anything.
Here is the core of it:
temp = list[j].getfirstName();
list[j].getfirstName() = list[j+1].getfirstName();
list[j+1].getfirstName() = temp;
getfirstName() returns the first name by value so all your assignments are doing is swapping temporary copies of the first names. There is no effect on the actual list elements.
I think you meant:
temp = list[j];
list[j] = list[j+1];
list[j+1] = temp;
This also means temp must be declared as a Student, not a std::string.
Also, unless I'm misremembering how Bubble Sort works (which is certainly possible — given its uselessness in the real world, it's been a long time since I've written one), your outer loop needs as many iterations as it takes for the inner loop not to be doing any swaps any more. If that's somehow inherently capped at numStudents iterations, I can't see why, nor see any evidence of it on the Wikipedia article.
Assuming I am on the right lines with that, I'd have the function looking like this:
void Course::sort_list()
{
bool go_again = false;
do {
go_again = false;
for (int i = 0; i < numStudents-1; i++) {
if (list[i].getfirstName() > list[i+1].getfirstName()) {
Student temp = list[i];
list[i] = list[i+1];
list[i+1] = temp;
go_again = true;
}
}
} while(go_again);
}
(live demo)

I don't know what is causing the segmentation fault in my code

I'm at my wit's end with this code and I am new to c++ so I don't even know where to begin to check for this error. What is causing the segmentation fault in my code and how do I fix it?
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
class Student
{
private:
string name;
int numClasses;
vector<string> classList;
public:
Student (string nameVal, int numClassesVal, string classListArr[]);
Student (string nameVal, int numClassesVal);
Student (string nameVal);
Student ();
void setName(string nameVal);
void setNumClasses(int numClassesVal);
void setClassList(string classListArr[]);
string getName();
int getNumClasses();
vector<string> getClassList();
void input();
void output();
void reset();
};
int main ()
{
Student user;
string answer;
int flag = 1;
while (flag == 1)
{
user.input();
user.output();
cout << "Do you want to enter the new data? (y/n)" << endl;
cin >> answer;
cin.ignore();
if (answer == "n")
{
flag == 0;
}
}
return 0;
}
Student::Student (string nameVal, int numClassesVal, string classListArr[])
: name(nameVal), numClasses(numClassesVal)
{
string test = classListArr[0];
for (int x = 0; x < 10; ++x)
{
if ( (x > 0) && (classListArr[x] == test))
break;
classListArr[x] = classList[x];
}
}
Student::Student (string nameVal, int numClassesVal)
{
name = nameVal;
numClasses = numClassesVal;
for (int x = 0; x < 10; ++x)
{
classList[x] = "";
}
}
Student::Student (string nameVal)
{
name = nameVal;
numClasses = 0;
for (int x = 0; x < 10; ++x)
{
classList[x] = "";
}
}
Student::Student ()
{
name = "";
numClasses = 0;
for (int x = 0; x < 10; ++x)
{
classList[x] = "";
}
}
void Student::setName(string nameVal) {name = nameVal;}
void Student::setNumClasses(int numClassesVal) {numClasses = numClassesVal;}
void Student::setClassList(string classListArr[])
{
string test = classListArr[0];
for (int x = 0; x < 10; ++x)
{
if ( (x > 0) && (classListArr[x] == test))
break;
classListArr[x] = classList[x];
}
}
string Student::getName() {return name;}
int Student::getNumClasses() {return numClasses;}
vector<string> Student::getClassList() {return classList;}
void Student::input()
{
string temp;
int classes;
cout << "Input Student's Name:" << endl;
getline(cin, temp);
name = temp;
cout << "Input Number of Classes:" << endl;
cin >> classes;
cin.ignore();
numClasses = classes;
for (int x = 0; x < 10; ++x)
{
if ( x == 9)
{
cout << "Input Last Class Name (Maximum of 10):";
getline(cin, temp);
classList[9] = temp;
}
else
{
cout << "Input Class Name:";
getline(cin, temp);
classList[x] = temp;
cout << "Do you have any more classes? (y/n):";
getline(cin, temp);
if ( temp == "n")
break;
}
}
}
void Student::output()
{
cout << "Student Name: " << name << "\nNumber of Classes: " << numClasses << endl;
cout << "Names of Classes: " << endl;
for (int x = 0; x < 10; ++x)
{
if ( numClasses == 0 )
break;
if ( x == 0 )
cout << "Names of Classes: \n";
if ( classList[x] == "" )
break;
cout << "(" << x << ") " << classList[x] << "\n";
}
}
void Student::reset()
{
numClasses = 0;
for (int x = 0; x < 10; ++x)
{
classList[x] = "";
}
}
I tried changing the main function from before where I had a goto statement instead of a flag, and that didn't fix it. I think it's the cin.getline() but I am not sure.
You have undefined behavior in this code (and the other constructors):
Student::Student ()
{
name = "";
numClasses = 0;
for (int x = 0; x < 10; ++x)
{
classList[x] = "";
}
}
You never allocated any elements in the classList vector, so the reference to classList[x] is out of bounds. You should use .push_back() to add new elements to the vector:
Student::Student ()
{
name = "";
numClasses = 0;
for (int x = 0; x < 10; ++x)
{
classList.push_back("");
}
}
Or before the loop you could do classList.reserve(10); to make room for 10 elements.
See C++ Tutorial: A Beginner's Guide to std::vector

c++ out of range at memory location error

Here is the code I have for a programing assignment I have. Im getting this error when I run the program
"Unhandled exception at at 0x772BC41F in STRUCT2.EXE: Microsoft C++ exception: std::out_of_range at memory location 0x0043ED04." If I understand this right, the error means my array has exceeded the allotted memory space. is that correct? and if this is correct, what am I doing wrong? My input file has less than 30 elements in it.
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>
#include <sstream>
#include <cctype>
using namespace std;
struct Element
{
string Name;
char eN1;
char eN2;
float Weight;
};
struct Formula
{
char Element1;
char ElementA;
int Atom;
};
void ELEMENTS(Element ElmAry[30]);
float Str2Float(string Weight);
void FORMULAS(Formula FormAry[30]);
float CalculateMoleculeWeight(Element ElmAry[30], Formula FormAry[30]);
int main()
{
ifstream inputFile1;
ifstream inputFile2;
ofstream outputFile;
inputFile1.open("Element.txt");
inputFile2.open("Formula.txt");
outputFile.open("Molecular Weight.txt");
Element ElmAry[30];
Formula FormAry[30];
char inputCh;
int i = 0;
string String1;
string mFor;
string ABRV;
int ElmDigit = 0;
float StringWeight = 0;
string Name;
string Weight;
int LENGTH = 0;
float MOLEWT;
if(!inputFile1)
{
cout << "Couldn't find the Element.txt file." << endl;
return 0;
}
if(!inputFile2)
{
cout << "Couldn't find the Formula.txt file." << endl;
return 0;
}
ELEMENTS(ElmAry);
while(inputFile1)
{
Name = String1.substr(0,2);
ElmAry[i].Name = Name;
Weight = String1.substr(3,10);
String1.clear();
StringWeight = Str2Float(Weight);
ElmAry[i].Weight = StringWeight;
i++;
}
i--;
FORMULAS(FormAry);
while (inputFile2)
{
getline(inputFile2,String1);
LENGTH = String1.length();
int j = 0;
int n = 0;
while( j < LENGTH)
{
int pos = 0;
pos = String1.find(')');
while(n < LENGTH)
{
inputCh = String1.at(n);
if(isalpha(inputCh) && isupper(inputCh))
{
FormAry[j].Element1 = String1.at(n);
n++;
inputCh = String1.at(n);
}
if(isalpha(inputCh) && islower(inputCh))
{
FormAry[j].ElementA = String1.at(n);
n++;
inputCh = String1.at(n);
}
if(ispunct(inputCh))
{
n++;
inputCh = String1.at(n);
ElmDigit = (inputCh-'0');
}
if(isdigit(inputCh))
{
FormAry[j].Atom = ElmDigit;
n++;
}
inputCh = String1.at(n);
j++;
if(iscntrl(inputCh))
{
n++;
inputCh = String1.at(n);
j++;
}
n++;
}
}
}
MOLEWT = CalculateMoleculeWeight(ElmAry, FormAry);
cout << "\t\t MOLECULAR WEIGHT CHART \t\t\n" << endl;
cout << "\n| FORMULA |\t " << "\t| ATOM.WT |" << endl;
cout << "_______________________________";
outputFile << "\t\t MOLECULAR WEIGHT CHART \t\t\n" << endl;
outputFile << "\n| FORMULA |\t " << "\t| ATOM.WT |" << endl;
outputFile << "_______________________________";
for (int a = 0; a < 30; a++)
{
cout << MOLEWT << endl;
outputFile << MOLEWT << endl;
}
inputFile1.close();
inputFile2.close();
outputFile.close();
cin.get();
cin.get();
return 0;
}
void ELEMENTS(Element ElmAry[30])
{
for(int i = 0; i < 30; i++)
{
ElmAry[i].Weight = 0;
}
}
void FORMULAS(Formula FormAry[30])
{
for(int x = 0; x < 30; x++)
{
for(int x = 0; x < 9; x++)
{
FormAry[x].Atom = 1;
}
}
}
float Str2Float (string x)
{
stringstream ss(x);
float StringWeight;
ss >> StringWeight;
return StringWeight;
}
float CalculateMoleculeWeight(Element ElmAry[30], Formula FormAry[30])
{
int i;
int j=0;
float MoleWT = 0;
float MoleSum = 0;
char e1;
char e2;
char f1;
char f2;
for(i = 0; i < 30; i++)
{
f1 = FormAry[j].Element1;
f2 = FormAry[j].ElementA;
e1 = ElmAry[i].eN1;
e2 = ElmAry[i].eN1;
if
(e1 == f1 && e2 == f2)
{
MoleWT = ElmAry[i].Weight * FormAry[j].Atom;
MoleSum = MoleSum + MoleWT;
j++;
}
}
return MoleSum;
}
when I get to
while(inputFile1)
{
Name = String1.substr(0,2);
ElmAry[i].Name = Name;
Weight = String1.substr(3,10);//invalid string position
String1.clear();
StringWeight = Str2Float(Weight);
ElmAry[i].Weight = StringWeight;
i++;
}
i--;
Weight = String1.substr(3,10); gives me an invalid string position
std::out_of_range is an exception you get when you attempt to access memory outside the space you've allocated (in an STL container). In this particular case, you are accessing areas of a std::string that has not been allocated:
Weight = String1.substr(3,10); // empty string or string.length() < 4 throws here
std::string::substr takes index parameters that must be within the bounds of the array encapsulated by std::string. If the string is only 2 characters long, and you attempt to get characters starting at the 4th position, you will see the std::out_of_range exception. You should check the length prior to doing this kind of operation.
Additionally, you are declaring your arrays:
Element ElmAry[30];
Formula FormAry[30];
But you are looping through an entire file (which potentially has more than 30 elements). Thus, when i >= 30, you are out of bounds (and behavior will be undefined).
You can fix that by using std::vector, which will allow the array to be dynamically sized, or another collection (e.g. std::list, std::deque).