Character in a string and endl char how?

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
void Program::LoadFile() {
	string fileName = "";
	ifstream inFile;
	cin.clear();
	cin.sync();
	cout << "Enter a filename: ";
	getline(cin, fileName);
	if (fileName.empty()) {
		cout << "Error: No filename given." << endl;
	}
	else {
		inFile.open(fileName.c_str(), ios::in);
		if (!inFile) {
			cout << "Error: File not found." << endl;
			return;
		}
		char *line1 = new char[512];
		char *line2 = new char[512];
		string fileKey = "#FILE#", line;
		char c;
		_employees.clear();
		bool myBool = false;
		getline(inFile, line);
		for (int i=0; i<6; ++i) {
			if (strcmp(fileKey.c_str(), line.c_str()) == 0)
				myBool = true;
			else
				myBool = false;
		}
		int cnt = 0;
		if(myBool) {
			while (inFile >> noskipws >> c) {
				line1[cnt] = c;
				if (c == ':')
					while (c != '\n') {
                        line2[cnt] = c;
                        ++cnt;
					}
		else if (c == '\n') {
		cnt = 0;
		AddEmployee(line1, (double)atof(line2));
		line1 = '\x0';
		line2 = '\x0';
		}
		++cnt;
	}
	inFile.close();
	cout << "Read " << cnt << " lines in file "
	     << "and loaded the Employee List."
	     << endl << endl;
    }
    else {
         cout << "Sorry cannot load the file." << endl
	<< "Wrong signature found." << endl;
	inFile.close();
	return;
    }
  }
}

So far that's what I've got and it doesn't work. Is there anyway to make it
work? What I've been trying to do for 10 hours now is... load a text file
like so:

#FILE#48027599
Some Name:<double> // double being a pay
Some Name:<double>
etc...

Then read first #FILE# (which will be my signature), the number
which will be held in a private variable for class. Finally,
the names looped in 1 string, the doubles in a double var. So
I can type them in my program like this:

Employee List #48027599
===========================================
John Doe: 32000
Jane Doe: 35000
===========================================

That's all. Please help me, oh and only C++ no C/C++... Thanks in advance.
Last edited on
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
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;

struct employee
{
	string name;
	double pay_rate;
};

int ID;
void load_data(vector<employee>& v)
{
	string t;
	getline(cin, t);
	ID = stoi(string(t.begin() + t.rfind("#") + 1, t.end()));

	employee e;
	while(getline(cin >> ws, e.name, ':') >> ws >> e.pay_rate)
	{
		v.push_back(e);
	}
}

int main() {
	vector<employee> employees;
	load_data(employees);
	
	cout << "ID: " << ID << endl;
	for(auto e : employees)
		cout << e.name << ": " << e.pay_rate << endl;
	
}


http://ideone.com/VBwq92
Well what I've got now compiles but, there is an assertion error. I'm using Visual Studio 2010.

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
void Program::LoadFile(vector<Employee> &v) {
	string t;
	v.clear();
	cin.clear();
	cin.sync();
	cout << "Enter filename: ";
	getline(cin, t);
	if (t.empty()) {
		cout << "Enter a filename next time." << endl;
		return;
	}
	else {
		string line;
		double line2 = 0;
		ifstream inFile(t.c_str(), ios::in);
		getline(inFile, line);
		_ID = stoi(string(line.begin() + line.rfind("#") + 1, line.end()));
		Employee e;
		while(!inFile.eof())
		{
			getline(inFile, line);
			line2 = stof(string(line.begin() + t.rfind(":") + 1, line.end()));
			line.erase(':');
			e.setName(line);
			e.setPayRate(line2);
			v.push_back(e);
		}
		cout << "Employee List " << _ID << " loaded." << endl;
	}
}


By the way, thanks for the quick reply..
EDIT: Forgot to tell the assertion failure.
The message was..
Expression: string iterator + offset out of range
Last edited on
Does the assertion error give any information?

I do see some issues, its not usually recommended you loop on EOF in c++, see how I do it in my example.
1
2
3
4
5
6
employee e;
        //         get up to but not the ':',   eat white space,  get pay_rate    
	while(getline(cin >> ws, e.name, ':') >> ws >> e.pay_rate)
	{
		v.push_back(e);//insert iff both vars load successfuly
	}


Also line.erase(':'); is incorrect, no version of string::erase takes a char to erase, see http://www.cplusplus.com/reference/string/string/erase/


EDIT:
The message was..
Expression: string iterator + offset out of range

Probably line 17 or 22, verify the char was found, for example ...
1
2
3
4
5
 std::size_t offset = line.rfind("#");
if(offset != std::string::npos)
{
    _ID = stoi(string(line.begin() + offset + 1, line.end()));
}
Last edited on
It works !! Yeah. Here is the code for what I was doing..

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
void Program::LoadFile(vector<Employee> &v) {
	string t;
	v.clear();
	cin.clear();
	cin.sync();
	cout << "Enter filename: ";
	getline(cin, t);
	if (t.empty()) {
		cout << "Enter a filename next time." << endl;
		return;
	}
	else {
		string line;
		double line2;
		ifstream inFile(t.c_str(), ios::in);
		if (!inFile.is_open()) {
			cout << "File not found!" << endl;
			return;
		}
		getline(inFile, line);
		size_t offset = line.rfind('#');
		if (offset != string::npos) {
			_ID = stoi(string(line.begin() + offset + 1, line.end()));
		}
		Employee e;
		while (getline(inFile >> ws, line, ':') >> ws >> line2) {
			e.setName(line);
			e.setPayRate(line2);
			v.push_back(e);
		}
		cout << "Employee List " << _ID << " loaded." << endl;
	}
}


This code works perfectly... hehe. I thank you guys for all your help. You guys pretty much solved it. Although you were getting input from the entire cin. I was trying for reading files.
Topic archived. No new replies allowed.