Tomasz Gutkowski
Tomasz Gutkowski

Reputation: 1418

How to return array of strings?

I have function:

int read_file() {
  ifstream file("plik");
  if(!file.is_open()) {
    throw -1;
  }
  int i = 0;
  string line[MAXSIZE];
  while(getline(plik, line[i])) {
    cout<<line[i]<<endl;
    i++;
  }

  return i; 
}

But i want to return array of strings:

line[]

How can I do this?

Upvotes: 2

Views: 10539

Answers (4)

Jerry Coffin
Jerry Coffin

Reputation: 490808

I'd advise against returning an std::vector<std::string> as well. Instead, I'd pass an iterator, and have the function write the data to wherever the iterator points. This way, the function can equally well write the data to a vector, or a deque, or (if you want) directly to an output stream.

Using that, your function borders on trivial:

// I've changed the definition slightly, to let you pass it a filename instead
// of hard-coding one.
//
template <class outIt>
void read_file(std::string const &filename, outIt output) { 
     std::ifstream in(filename);
     std::string line;

     while (std::getline(in, line))
         *output++ = line;
}

To use this to copy the data to standard output, roughly as in the question, you'd do something like:

read_file("plik", std::ostream_iterator<std::string>(std::cout, "\n"));

Upvotes: 2

razlebe
razlebe

Reputation: 7144

If you really, really wanted to, you could dynamically allocate an array and return a pointer to that array:

std::string* getArray() 
{
  return (new std::string[10]);
}

BUT you then need to cater for freeing up the memory you allocated using delete[] to avoid a memory leak.

Ask yourself:

  • Which bit of your code should be responsible for doing this?
  • Will you remember that that pointer represents a dynamically-allocated array later on, elsewhere in your code?
  • What happens if you pass that pointer around your program and accidentally use it somewhere after another bit of code has called delete[] on it? (Segmentation fault is the answer).
  • If you pass a pointer to an array around, how does the code that uses that pointer know the size of your array? std::vector keeps count of the items for you, so no problem there.

That's why using an std::vector<std::string> is a better idea. Returning a pointer to a dynamically allocated array introduces all sorts of problems that are better avoided than solved.

Upvotes: 3

aschepler
aschepler

Reputation: 72473

Standard 8.3.5p6:

Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things.

As @Tomalak hinted, Just Say No to arrays. They're related to all sorts of gotchas that you can usually avoid if you can use a vector instead.

Upvotes: 3

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

Don't. Arrays are not copyable.

Use a std::vector<std::string> instead.

Upvotes: 14

Related Questions