Trying to make a database

I am writing and reading from a text file, I'm just messing around trying to get a little bit of the hang of C++, and yes I already know the code looks like garbage, but could you help explain why I am getting an exception thrown here? What does it mean? https://i.gyazo.com/d82df0a249a9a004c4cd492a9842d50c.png
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <limits>
using namespace std;

struct Student{
	string name;
	int age;
	int grade=0;
	int sid;
};
ifstream& GotoLine(std::ifstream& file, unsigned int num) {
	file.seekg(std::ios::beg);
	for (int i = 0; i < num - 1; ++i) {
		file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}
	return file;
}


int main()
{
	ifstream inFile("data.txt");
	int numStudents = 0;
	string tempName[2];
	string command;
	int tempAge;
	int tempGrade;
	int tempSID;
	Student * studentRecords;
	studentRecords = new Student[0];
	bool making = true;
	cout << "Would you like to initalize from data file?" << endl;


	while (making) {
		cin >> command;
		if (command == "yes") {
			if (inFile.fail()) {
				cerr << "Data file not found/opened." << endl;
				exit(1);
			}
			inFile >> numStudents;
			studentRecords = new Student[numStudents];
			int sidCheck = -1;
			for (unsigned int i = 0; i < numStudents; i++) {
				GotoLine(inFile, (i * 4) + 1);
				inFile >> sidCheck;
				if (sidCheck < -1)
				{
					i = numStudents;
				}
				else
				{
					studentRecords[sidCheck].sid = sidCheck;
					inFile >> studentRecords[sidCheck].name;
					inFile >> studentRecords[sidCheck].age;
					inFile >> studentRecords[sidCheck].grade;
				}
			}
			making = false;
		}
		else if (command == "no") {
			cout << "How many students attend the school?" << endl;
			cin >> numStudents;
			making = false;
			studentRecords = new Student[numStudents];
		}
		else
		{
			cout << "Unknown command" << endl;
		}

	}




	cout << "Initialized " << numStudents << " records" << endl;
	int numRecordsLoaded=0;
	for (unsigned int i = 0; i < numStudents; i++) {
		if (studentRecords[i].age != 0 & studentRecords[i].age < 100) {
			cout << studentRecords[i].age << endl;
			numRecordsLoaded++;
		}
	}
	cout << numRecordsLoaded  << " valid records found." << endl;
	cout << endl;
	cout << endl;
	cout << endl;
	cout << "Would you like to add, clear, list, or load a record?" << endl;
	cin >> command;
	while (command != "exit") {
		if (command == "add") {
			cout << "What is their first name?" << endl;
			cin >> tempName[0];
			cout << "What is their last name?" << endl;
			cin >> tempName[1];
			cout << "What is their age?" << endl;
			cin >> tempAge;
			cout << "What is their grade?" << endl;
			cin >> tempGrade;
			cout << "What is their ID?" << endl;
			cin >> tempSID;
			studentRecords[tempSID] = { tempName[0]+ " " + tempName[1],tempAge,tempGrade };
			cout << "Student " << tempSID << " has been registered." << endl;
			cout << "----------------------------------------------" << endl;
			cout << "Would you like to add, clear, list, or load a record?" << endl;
		}
		else if (command == "load") {
			cout << "Which student would you like to search? (ID)" << endl;
			cin >> tempSID;
			cout << "Student "<< tempSID << " loaded." << endl;
			cout << "----------------------------------------------" << endl;
			cout << "Name: " << studentRecords[tempSID].name << endl;
			cout << "Age: " << studentRecords[tempSID].age << endl;
			cout << "Grade: " << studentRecords[tempSID].grade << endl;
			cout << "----------------------------------------------" << endl;
			cout << "Would you like to add, clear, list, or load a record?" << endl;
		}
		else if (command == "clear") {
			cout << "Which record would you like to clear? (ID)" << endl;
			cin >> tempSID;
			studentRecords[tempSID] = { "",0,0,tempSID};
			cout << "Record " << tempSID << " cleared." << endl;
			cout << "----------------------------------------------" << endl;
			cout << "Would you like to add, clear, list, or load a record?" << endl;
		}
		else if (command == "list") {
			int fuck=0;
			for (int i = 0; i < numStudents; i++) {
				if (studentRecords[i].age != 0) {
					cout << studentRecords[i].name << " ID: " << studentRecords[i].sid << endl;
					fuck++;
				}
			}
			cout << fuck << " records loaded." << endl;
		}
		else {
			cout << "Unkown Command" << endl;
		}
		tempName[0,1] = "N/A";
		tempSID = 0;
		tempAge = 0;
		tempGrade = 0;
		tempSID = 0;
		cin >> command;
	}
    return 0;
}
Hello Nichismoke,

Welcome to the forum.

I can not duplicate your error at this time because the program will not compile for me.

Some problems I have noted:

"data.txt" I do not have the information that you are using. I could create this file, but there is no guarantee that what I crate will be correct. When you post a program that reada a data file it is best to include the file or at least a sample of the file so people do not have to guess at what is in the file.

1
2
Student * studentRecords;
studentRecords = new Student[0];


Line 1 is OK.
Line 2. is likely creating a "nullptr" or it is creating a pointer to nothing because there is no size to the lock of memory that being created. what is between the [] needs to have a size like 5 or 10 or even a variable for the size. Also "new" returns a void pointer, so you may want to typecast the return value to what you need.

You might want to read this: http://www.cplusplus.com/reference/new/operator%20new[]/

Through out your program you need to be consistent. Some of your for loops define "i" as being an "int", but in the middle you are comparing that "int" to an "unsigned int". This flags a warning, but not enough to be a problem.

Some of your code looks like this: else if (command == "clear") {, but in other places you use:
1
2
else if (command == "clear")
{

This second example makes the code easier to read when the {} line up in the same column. Just saying because either way works. It is better to be consistent with either way.

Your line 42 may work, but i have seen this more often written as if (!inFile) or if (!inFile.open(). Either way it is less restrictive as to what went wrong.

Line 108 does not work. First "studentRecords" has no storage space then you are trying to initialize an object of type "Student", but the point of using the "new" to create an array each element of the array would already be an object of type "Student" you would have to access each variable of the struct togive it a new value or create a function to do this.

Line 133 may be funny to you, but not everyone.

Last the error you first mentioned is not in your code, but in the header file "local". One of your original include statements has included the header file "local" and something in the program is using this function. Where I am not sure yet until I can get the program to compile run.

Just out of curiosity what version of VS are you using?

Hope that helps,

Andy
I am using Visual Studio 2017.
My data file goes as follows:
1
2
3
4
5
6
7
8
9
10
10
8
John Green
16
10
2
Jackson Diver
15
10


Line 2. is likely creating a "nullptr" or it is creating a pointer to nothing because there is no size to the lock of memory that being created. what is between the [] needs to have a size like 5 or 10 or even a variable for the size. Also "new" returns a void pointer, so you may want to typecast the return value to what you need.


So I should I change the order in which it is created so that I do have the variable size, like 100 students? I will also read up on typecast too, thank you.

I will also start using brackets in the way you mentioned to make it easier for everyone to read. In the future.

Line 108 does not work. First "studentRecords" has no storage space then you are trying to initialize an object of type "Student", but the point of using the "new" to create an array each element of the array would already be an object of type "Student" you would have to access each variable of the struct to give it a new value or create a function to do this.


Could I use a constructor to give each object a value beforehand? When I read over the line, I don't see how it couldn't have storage space, considering I've already created the array of the students as studentRecords. In an earlier version of this, where I hadn't implemented a data text file, that line works, and I believe it still works if I just manually type in the number of students that need to be created at the top by saying "No" to the first question the program asks when it starts up.

Thank you for your insight and help. I am grateful I was able to get such a detailed response.
Hello Nichismoke,

I refer you to the code in your first post. Line 33 I would write as Student * studentRecords = nullptr; and delete line 34. At this point all you need is to define the variable because later you will give this pointer a proper address to use.

Line 108 does not work. First "studentRecords" has no storage space
. Looking back I do not remember what I meant by this. Using ctor a second or third time is not allowed as this is called once when the object is created. So when the array is created each element of the array creates an object of "Student" and the ctor is called to create the object. What you can do with a struct is:
1
2
3
4
5
6
7
struct Student
{
	std::string name;
	int age{};
	char grade{};
	int sid{};
};

You can not do this with a class, but it does work with a struct.

Seeing you input file I do see a problem during reading. Line 59 will read the name until the first white space is reached. Leaving the file pointer at the beginning of the second part of the name, yet the next line of code is expecting a numeric value which will cause "inFile" to fail and nothing else will be read from the file. My first attempt to fix this line was to call a function to change the values of the needed array element. Later I noticed that i could do cin >> studentRecords[index].vaiable of struct;. Which worked for everything except the name which I used what you had before I saved it to the struct. You could also replace the two variables with "std::getline()".

As I look over the program I see the use of "sid" especially as an array subscript is a bad idea. The "sid" should be a number unique to each student or generated by the program to eliminate the chance of a duplicate number. This way you could start the "sid" at zero to make use of the whole array.

Now that I know what the input file looks like I will have to put more time into the read part.

If I have missed anything let me know.

Hope that helps,

Andy
Topic archived. No new replies allowed.