0

I want to put some text from a text file into an array, but have the text in the array as individual characters. How would I do that?

Currently I have

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

int main()
{
  string line;
  ifstream myfile ("maze.txt");
  if (myfile.is_open())
  {
    while ( myfile.good() )
    {
      getline (myfile,line);
      // --------------------------------------
      string s(line);
      istringstream iss(s);

    do
    {
        string sub;
        iss >> sub;
        cout << "Substring: " << sub << endl;
    } while (iss);
// ---------------------------------------------
    }
    myfile.close();
  }
  else cout << "Unable to open file"; 
  system ("pause");
  return 0;
}

I'm guessing getline gets one line at a time. Now how would I split that line into individual characters, and then put those characters in an array? I am taking a C++ course for the first time so I'm new, be nice :p

forthewinwin
  • 3,555
  • 4
  • 17
  • 17
  • You might want to look again at exactly what the various function in the C++ (and especially the c) standard library *do*. Odds are that you are making this harder than you need to because you you've misunderstood something about either strings or IO on c-like languages. – dmckee --- ex-moderator kitten May 24 '12 at 22:44
  • 2
    a `std::string` refers to an array of characters, why do you want to put them into another array? Also, your `fstream` code is badly written, did you copy it from the useless cplusplus.com by any chance? – Jonathan Wakely May 24 '12 at 22:49
  • 3
    [Do not loop while good()](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). (That question title mentions eof, but the same issue is here: the check is before the input). – R. Martinho Fernandes May 24 '12 at 23:00
  • Alright got it thanks :D – forthewinwin May 24 '12 at 23:15

2 Answers2

8
std::ifstream file("hello.txt");
if (file) {
  std::vector<char> vec(std::istreambuf_iterator<char>(file),
                        (std::istreambuf_iterator<char>()));
} else {
  // ...
}

Very elegant compared to the manual approach using a loop and push_back.

  • Arghh you beat me to it :P. You might want to add that not only is it more elegant, it is also significantly more efficient than push_back(). – cristicbz May 24 '12 at 22:51
  • That is nice. I so rarely use the istreambuf_iterator that I forget it exists! – Chris Hayden May 24 '12 at 22:56
  • 4
    @cristicbz: I don't think it's any more efficient than push_back actually – Mooing Duck May 24 '12 at 23:07
  • 1
    @cristicbz I doubt it is any more efficient at all, much less significantly more. The vector constructor is implemented with that same loop. – R. Martinho Fernandes May 24 '12 at 23:10
  • Now how would I do something with say, the first character? I have no experience with vectors... Say for example, I just want to see if the first character is equal or something. Just doing this to try to grasp the concept(s). – forthewinwin May 24 '12 at 23:12
  • 1
    `char first = vec.at(0); if (first == 'A') {…}` –  May 24 '12 at 23:13
  • 1
    I suggest you pick up a [good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). –  May 24 '12 at 23:16
  • I'm guessing vec.at(0) refers to the first item in the vector, and in the code above, vec is the vector? Just making sure – forthewinwin May 25 '12 at 02:26
  • @forthewinwin: You are correct, `at(0)` returns a reference to the element at index 0. You can also say `vec[0]` just like an array. There is a difference though, using `at()` will also perform bounds-checking and throw an exception for an invalid index. – Blastfurnace May 25 '12 at 04:06
  • 1
    I would prefer *at* over *[]* here, because you don't know how big the file was. Maybe the file was empty. Doing *[0]* on an empty vector can order a pizza if it likes. –  May 25 '12 at 08:30
  • @forthewinwin if this question answered your question, you might want to mark it as accepted by clicking the gray checkmark. That way, future visitors know where to look. –  May 25 '12 at 13:21
  • Ah just one more question: say if I had three rows of "Hello" in my text file, all 3 stacked on each other. vec.at(0) would be 'H', vec.at(4) would be 'o', but why would vec.at(6) be 'H' and vec.at(5) be a blank space? Is it just how C++ works? – forthewinwin May 25 '12 at 17:23
  • 1
    @forthewinwin those shouldn't return anything but rather throw an exception. `vec[5]` and `vec[6]`, on the other hand, can do whatever they want, be it what you get, order a pizza or get you pregnant (this is called *undefined behavior*, which, when invoked, can do anything). –  May 25 '12 at 17:28
3
#include <vector>
#include <fstream>

int main() {
  std::vector< char > myvector;
  std::ifstream myfile("maze.txt");

  char c;

  while(myfile.get(c)) {
    myvector.push_back(c);
  }
}
Chris Hayden
  • 1,064
  • 5
  • 6