0

Let's say I have a file of names such as:

"erica","bosley","bob","david","janice"

That is, quotes around each name, each name separated by a comma with no space in between.

I want to read these into an array of strings, but can't seem to find the ignore/get/getline/whatever combo to work. I imagine this is a common problem but I'm trying to get better at file I/O and don't know much yet. Here's a basic version that just reads in the entire file as one string (NOT what I want, obviously):

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

fstream iFile("names.txt", ios::in);
string names[5];

int index = 0;
while(iFile)
{
    iFile >> names[index];
    index++;
}

for(int i = 0; i < 5; i++)
{
    cout << "names[" << i << "]: " << names[i] << endl;
}

Output:

names[0]: "erica","bosley","bob","david","janice"
names[1]:
names[2]:
names[3]:
names[4]:

Also, I understand why it all gets read as a single string, but then why are the remaining elements not filled with garbage?

To be clear, I want the output to look like:

names[0]: erica
names[1]: bosley
names[2]: bob
names[3]: david
names[4]: janice
bcf
  • 1,928
  • 21
  • 37
  • 1
    `std::string` initializes to an empty string when it doesn't have another initializer. – Joe Z Dec 21 '13 at 04:51
  • If it were me, I would get the input into a single line, and then write a loop involving `find_first_of` to pick the line apart manually. But maybe I'm old school? – Joe Z Dec 21 '13 at 04:52
  • Can the quoted strings have commas in them? Can the quoted strings have quotes in them (via some kind of escape)? – RichardPlunkett Dec 21 '13 at 05:06
  • @RichardPlunkett No, each quoted string has ASCII values 97-122 only. – bcf Dec 21 '13 at 05:12

2 Answers2

6

The easiest way to handle this:

  1. Read the entire file and place it into a string, Here is an example of how to do it.
  2. Split the string that you got from number 1. Here is an example of how to do that.
Community
  • 1
  • 1
Caesar
  • 8,395
  • 6
  • 34
  • 62
0

Stream extraction delimits by a space. Therefore the entire file gets read as one string. What you want instead is to split the string by commas.

#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>

fstream iFile("names.txt", ios::in);
string file;

iFile >> file;

std::istringstream ss(file);
std::string token;

std::vector<std::string> names;

while(std::getline(ss, token, ',')) {
    names.push_back(token);
}

To remove the quotes, use this code:

for (unsigned int i = 0; i < names.size(); i++) {
     auto it = std::remove_if(names[i].begin(), names[i].end(), [&] (char c) { return c == '"'; });
     names[i] = std::string(names[i].begin(), it);
}

remove_if returns the end iterator for the transformed string, which is why you construct the new string with (s.begin(), it).

Then output it:

for (unsigned int i = 0; i < names.size(); i++) {
    std::cout << "names["<<i<<"]: " << names[i] << std::endl;
}

Live Example