EXPECTING HELP WITH THE SEGMENTATION FAULT

Hi, I have been dealing with the segmentation fault of this programme for a very long time. And, I can't seem to find what exactly is the problem. I was wondering if anyone could help me get rid of this problem. The code for the programme is below:

[indent]

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

//Define a class to represent each Seismic Activity measurement event...

class RedwoodBaySeismicData {
string LocationID; //This is the station that owns this piece of data…
string Date; //The date that the values were collected…
string Time; //The time of day that the values were collected…
double SeismicSize; //Magnitude of Earthquake


public:
RedwoodBaySeismicData();
RedwoodBaySeismicData(string, string, string, double);

//The first group of member functions are used to change values...
//Functions are defined in the form of inlines.

void SetID(string ID) { LocationID = ID; }
void SetDate(string Day) { Date = Day; }
void SetTime(string Hour) { Time = Hour; }
void SetSeismicSize(double Magnitude) {SeismicSize = Magnitude; }


//The second group allows controlled access to individual value in the class...

string GetID() { return LocationID; }
string GetDate() {return Date; }
string GetTime() {return Time; }
double GetSeismicSize() { return SeismicSize;}


};

//The default constructor sets the private variable members to a harmless value...

RedwoodBaySeismicData::RedwoodBaySeismicData()
{
LocationID = "";
Date = "";
Time = "";
SeismicSize = 0.0;

}

//This initializing constructor allows you to create a object with value already set...

RedwoodBaySeismicData::RedwoodBaySeismicData(string ID, string Day, string Hour, double Magnitude)
{
LocationID = ID;
Date = Day;
Time = Hour;
SeismicSize = Magnitude;

}

class RedwoodBayDataList {
vector<RedwoodBaySeismicData> RedwoodBayDataSpots; //Create a collection of location information...
string FileName ;
public:
RedwoodBayDataList() {FileName = "RedwoodBaySeismicEventList.Data";}


void PostSeismicInfo();
void WeeklyReport();
};




//Allow the user to post the values for each location...

void RedwoodBayDataList::PostSeismicInfo()
{
int K;
string Line, ID, Date, Hour;
double Magnitude;
fstream InFile("RedwoodBaySeismicEventList.data", ios::in);
//...then get the values for each location...
RedwoodBaySeismicData Buffer;


for(K = 0 ; K < 69 ; K++) {

getline(InFile, Line);
ID = Line.substr(0,4);
Date = Line.substr(6,7);
Hour = Line.substr(9,3);
Magnitude = atof(strtok((char*)Line.c_str(), " ") );



Buffer.SetID(ID); //Use these values to load the Buffer record...
Buffer.SetDate(Date);
Buffer.SetTime(Hour);
Buffer.SetSeismicSize(Magnitude);
RedwoodBayDataSpots.push_back(Buffer);

RedwoodBayDataSpots[K].SetID(ID);
RedwoodBayDataSpots[K].SetDate(Date);
RedwoodBayDataSpots[K].SetTime(Hour);
RedwoodBayDataSpots[K].SetSeismicSize(Magnitude);

cin.ignore(100,'\n'); //This flushes the input buffer of any extra characters.

}

}
//This produces the final product...the report on Seismic Activiies.....

void RedwoodBayDataList::WeeklyReport()
{
int Count;

cout << "\n\t=============================================================" << endl; //This section is the report...it's really all about the formatting...
cout << "\tWeekly Report" << endl;
cout << "\t===============================================================" << endl;
cout << "\tLocation\tDate\tHour\tMagnitude" << endl;
cout << "\t===============================================================" << endl;
for(Count = 0 ; Count < 69 ; Count++)
cout << "\t" << RedwoodBayDataSpots[Count].GetID() << "\t" << RedwoodBayDataSpots[Count].GetDate() << "\t" << RedwoodBayDataSpots[Count].GetTime() << "\t" << RedwoodBayDataSpots[Count].GetSeismicSize();
cout << "\t===============================================================\n\n" << endl;
}

//Declare the functions...

void RunIT();
void Menu();


int main()
{
RunIT();
}

//This function implements a simple command processor...

void RunIT()
{
RedwoodBayDataList RedwoodBayDataSpots;
string Command = "";

while(Command != "Quit") {
Menu();
cout << "Command: ";
getline(cin, Command);


if(Command == "Report")
RedwoodBayDataSpots.WeeklyReport();
}
}

//This function tells the user what he or she can do...

void Menu()
{
cout << "Choices...................................................." << endl;
cout << "-----------------------------------------------------------" << endl;
cout << "\tReport...displays the report." << endl;
cout << "\tQuit.....exits the program." << endl;
cout << "-----------------------------------------------------------" << endl;
}


[/indent]
So close with the code tags. They're actually [code], not [indent].

Anyway, what line does the segfault occur on?
If you run it with a debugger it will tell you the line that causes the segFault, and let you check the values of each variables to see which one is causing the problem.
It looks mostly ok, but you have:
1
2
3
4
5
6
for(K = 0 ; K < 69 ; K++) {
    getline(InFile, Line);
    ID = Line.substr(0,4);
    Date = Line.substr(6,7);
    Hour = Line.substr(9,3);
    Magnitude = atof(strtok((char*)Line.c_str(), " ") );
You have lots of magic numbers there. What do they mean? Are they correct?

You have a call to strtok() without checking the result.

Did you know that strtok() modifies the buffer? You're passing in a string which allows users to see a const representation. You are then casting away that const to satisfy strtok(), but that's a serious error too.
This line

Magnitude = atof(strtok((char*)Line.c_str(), " ") );

is a good candidate for a crash. Never cast away const.

std::string provides enough functions to modify Line as you want to


This

1
2
3
4
RedwoodBayDataSpots[K].SetID(ID);
RedwoodBayDataSpots[K].SetDate(Date);
RedwoodBayDataSpots[K].SetTime(Hour);
RedwoodBayDataSpots[K].SetSeismicSize(Magnitude);


might crash also if RedwoodBayDataSpots.size() < 69
Sorry guys, I am new to this forum. So, I did not know how to submit the code for the programme in a proper way. Anyway, I am submitting my code again:

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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

//Define a class to represent each Seismic Activity measurement event...

class RedwoodBaySeismicData  {
  string LocationID;  	//This is the station that owns this piece of data…
  string Date;  		 //The date that the values were collected…
  string Time;  		//The time of day that the values were collected…
  double SeismicSize; 	//Magnitude of Earthquake
  

public:
  RedwoodBaySeismicData();
  RedwoodBaySeismicData(string, string, string, double);

  //The first group of member functions are used to change values...
  //Functions are defined in the form of inlines.

  void SetID(string ID)					{ LocationID = ID; }
  void SetDate(string Day)			{ Date = Day; }
  void SetTime(string Hour)			{ Time = Hour; }
  void SetSeismicSize(double Magnitude)	{SeismicSize = Magnitude; }
  

  //The second group allows controlled access to individual value in the class...

  string GetID()				{ return LocationID; }
  string GetDate()			{return Date; }
  string GetTime()			{return Time; }
  double GetSeismicSize()	{ return SeismicSize;}  
  

};

//The default constructor sets the private variable members to a harmless value...

RedwoodBaySeismicData::RedwoodBaySeismicData()
{
	LocationID = "";
	Date = "";
	Time = "";
	SeismicSize = 0.0;
	
}

//This initializing  constructor allows you to create a object with value already set...

 RedwoodBaySeismicData::RedwoodBaySeismicData(string ID, string Day, string Hour, double Magnitude)
{
	LocationID = ID;
	Date = Day;
	Time = Hour;
	SeismicSize = Magnitude;
	
}
 
 class RedwoodBayDataList  {
	vector<RedwoodBaySeismicData> RedwoodBayDataSpots;  //Create a collection of location information...
    string FileName ;
public:
	RedwoodBayDataList()  {FileName = "RedwoodBaySeismicEventList.Data";}

    
    void PostSeismicInfo();
    void WeeklyReport();
};




//Allow the user to post the values for each location...

void RedwoodBayDataList::PostSeismicInfo()
{
	int K;
	string Line, ID, Date, Hour;
	double Magnitude;
    fstream InFile("RedwoodBaySeismicEventList.data", ios::in);
	//...then get the values for each location...
	RedwoodBaySeismicData Buffer;


	for(K = 0 ; K < 69 ; K++)  {
          
        getline(InFile, Line);
		ID = Line.substr(0,4);
		Date =  Line.substr(6,7);
		Hour = Line.substr(9,3);
		Magnitude = atof(strtok((char*)Line.c_str(), " ") );
		 
		
        
        Buffer.SetID(ID);    //Use these values to load the Buffer record...
		Buffer.SetDate(Date);	
		Buffer.SetTime(Hour);
     	Buffer.SetSeismicSize(Magnitude);
        RedwoodBayDataSpots.push_back(Buffer);

		RedwoodBayDataSpots[K].SetID(ID);
		RedwoodBayDataSpots[K].SetDate(Date);
		RedwoodBayDataSpots[K].SetTime(Hour);
		RedwoodBayDataSpots[K].SetSeismicSize(Magnitude);

	cin.ignore(100,'\n');  //This flushes the input buffer of any extra characters.

}

}
//This produces the final product...the report on Seismic Activiies.....

void RedwoodBayDataList::WeeklyReport()
{
	int Count;

    cout << "\n\t=============================================================" << endl;  //This section is the report...it's really all about the formatting...
    cout << "\tWeekly Report" << endl;
    cout << "\t===============================================================" << endl;
	cout << "\tLocation\tDate\tHour\tMagnitude" << endl;
    cout << "\t===============================================================" << endl;
	for(Count = 0 ; Count < 69 ; Count++) 
		cout << "\t" << RedwoodBayDataSpots[Count].GetID() << "\t" << RedwoodBayDataSpots[Count].GetDate() << "\t" << RedwoodBayDataSpots[Count].GetTime() << "\t"  << RedwoodBayDataSpots[Count].GetSeismicSize();
        cout << "\t===============================================================\n\n" << endl;
}

//Declare the functions...

void RunIT();
void Menu();


int main()
{
	RunIT();
}

//This function implements a simple command processor...

void RunIT()
{
	RedwoodBayDataList RedwoodBayDataSpots;
	string Command = "";

	while(Command != "Quit")  {
		Menu();
		cout << "Command: ";
        getline(cin, Command);

		
	    if(Command == "Report")
			RedwoodBayDataSpots.WeeklyReport();
	}
}

//This function tells the user what he or she can do...

void Menu()
{
	cout << "Choices...................................................." << endl;
	cout << "-----------------------------------------------------------" << endl;
	cout << "\tReport...displays the  report." << endl;
	cout << "\tQuit.....exits the program." << endl;
	cout << "-----------------------------------------------------------" << endl;
}
The problems I've mentioned are on line 94 / 104 to 107
Hi Coder777. Thanks for your response. Do you happen to know the way of reading the "Magnitude" variable from the file without using "strtok". The thing is that since "Magnitude" is a double variable I can't use the "substr" like I did for other variables in order to read it from the file
since "Magnitude" is a double variable I can't use the "substr"
Why not?

The equivalent to that line would be:

Magnitude = atof(Line.substr(0, Line.find(" ")).c_str() );

It still looks wrong since it may include all the previous variables. What are you trying to accomplish with this

Magnitude = atof(Line.substr(0, Line.find(" ")).c_str() );

It still looks wrong since it may include all the previous variables. What are you trying to accomplish with this


I am just trying to read the value of "Magnitude" from the text file. The sample line of the text file looks like this:


Alpha:01232012:0100:2.7


Note:
"Alpha" represents ID
"01232012" represents Date
"0100" represents Hour
"2.7" represents Magnitude
Topic archived. No new replies allowed.