0

Say I have a textfile "Employees.txt" with Employee name and ID.

Like so:

John:d4250
Sarah:s5355
Alan:r4350

If I have a very very basic Employee class which has a constructor for Name and ID and I wish to read from this textfile and insert them into a vector

Am I best to use something like:

void GenericProgram::loadEmployees()
{
 string line;

 ifstream empFile("employees.txt");
 if(empFile.fail())
   {
    cout << "input file opening failed\n" << endl;
    exit(EXIT_FAILURE);
   }

     while (!empFile.eof())
     {
        string empName;
        string empID;

        while (getline(empFile, line, '\n'))
        {
            // this will give me the line on its own

            // now how to delimit again using ':'

            // then do something like
            Employee e(empName, empID)
            employeeVector.push_back(e);


        }
        empFile.close();
    }

}

I apologise that this is so basic. Brain is failing on me. I was wondering if there are better ways to read from files to populate objects with streams.

Jongware
  • 21,058
  • 8
  • 43
  • 86

1 Answers1

0

Just add to your code

int pos = line.find(":", 0);
if (pos != std::string::npos)
{
   std::string empName(line.begin(), line.begin() + pos);
   std::string empID(line.begin() + pos + 2, line.end());
}

For multiple ":"

std::vector<std::string> str;
std::vector<size_t> positions;
positions.push_back(0);
do
{
   positions.push_back(line.find(":", positions.size() - 1));
}
while(positions[positions.size() - 1] != std::string::npos);
for (int i = 0; i < positions.size(); i+=2)
{
   str.push_back((line.begin() + positions[i], line.begin() + positions[i+1]));
}

But i haven`t tested it.

  • I get this error from 'line' on the third line with empID: std::string line Error: no instance of constructor "std::basic_string<_elem _alloc="" _traits="">::basic_string[with _Elem=char, _Traits=std::char_traits,_Alloc=std::allocator]" matches the argument list argument types are: (std::_String_iterator>>, const size_t) I assume you meant to insert this inside : while (getline(empFile, line, '\n')) – user3665874 Nov 22 '14 at 16:35
  • Oh my bad. Sorry. std::string empID(line.begin() + pos + 2, line.end()); – Alexey Romaniuk Varser Nov 22 '14 at 16:37
  • Thanks a lot :) What should I search for to read up about this method? – user3665874 Nov 22 '14 at 16:39
  • @user3665874 careful, unless you're assume you're always parsing direct data directly (eg. what about a line with no ':') this will fail. – WhozCraig Nov 22 '14 at 16:45
  • And what happens if there is no `':'` in the line? As a general rule, either use the standard functions of `` (whose `std::find` will return the end iterator if it doesn't find the character), or use `std::string::substr()` (which accepts length of `std::string::npos`) with the results of the member functions of `std::string`. (Although in this case, I suspect that some wort of error handling would be appropriate, maybe doing nothing but outputting an error message if there is no `':'`.) – James Kanze Nov 22 '14 at 16:51
  • If there are no ":" in line. The function return std::string::npos. It`s equivalent to size of your array. You need to use something like this: if (pos != std::string::npos) { //good } else { //there are no : in your line } – Alexey Romaniuk Varser Nov 22 '14 at 17:11
  • Does anyone know what to search for to read up about this? I want to do the same thing for when there are more than one ":" in the line. – user3665874 Nov 23 '14 at 09:23
  • There are many ways to do this. You can do it by using only std::string. Or using CString. Or you can use stl algorithms. I saw in your code std::string and suggested this method. You need to know find method in std::string. I read about methods in http://www.cplusplus.com. For example std::string::find is here: http://www.cplusplus.com/reference/string/string/find/ – Alexey Romaniuk Varser Nov 23 '14 at 09:50
  • Alright thanks a lot, will do :) With a file with multiple ":" when I use this "line.begin() + pos + 1, line.end()" on my second string I start at the correct position but then I get the entire remaining line (I assume because of line.end()). Do I need to use find(":") to stop at the next ":" then? – user3665874 Nov 23 '14 at 10:19
  • It`s will be better to find all positions first. std::vector positions; int pos = 0; while(pos != std::string::npos) { pos = line.find(":", pos); positions.push_back(pos); } and then create an array of strings – Alexey Romaniuk Varser Nov 23 '14 at 12:46