1

I'm trying to open a file and read it word by word. I can't figure out where my issue is as it seems to break down after opening the file.

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <vector>
#include <array>

using namespace std;

int main()
{
    string path, test;
    ifstream inputFile;
    vector<string> words;

    cout << "What is the path for the input file? ";
    getline(cin, path);
    inputFile.open(path, ios::in);
    while (!inputFile.eof())
    {
        cin >> test;
        words.push_back(test);
    }
    for (int i = 0; i < words.size(); i++)
    {
        cout << words.at(i) << endl;
    }
    inputFile.close();
    return 0;
}
Paul Roub
  • 35,100
  • 27
  • 72
  • 83
pdsnowden
  • 37
  • 5
  • _as it seems to break down after opening the file_. Can you elaborate on that? – Algirdas Preidžius Jan 07 '16 at 22:23
  • Just as an aside, you can iterate through `words` like: `for(auto &it : words) std::cout << it << std::endl;`. This will be more c++11 and less ansi c. – theoden8 Jan 07 '16 at 22:31
  • When I use the local windows debugger it crashes right after the openfile command is ran. – pdsnowden Jan 07 '16 at 22:33
  • Also don't use `std::endl` prefer to use `"\n"`. The `std::endl` forces a flush which is almost certainly not what you want and will reduce your throughput dramatically. – Martin York Jan 07 '16 at 23:01
  • Instead of creating `inputFile` at the top of `main` and opening it after getting the file name, just create it after getting the file name: `std::ifstream inputFile(path);`. There's no need for `ios::in` There since it's an `ifstream`. And there's no need to close it later because the destructor will do that. – Pete Becker Jan 07 '16 at 23:21
  • In the output loop, `i` can't be out of range, so the range check in `vector::at` just wastes time. Use `words[i]` instead. – Pete Becker Jan 07 '16 at 23:25

3 Answers3

4
while (!inputFile.eof())
{
    cin >> test;
    words.push_back(test);
}

There are two problems here:

  1. You opened inputFile but then attempt to read from std::cin

  2. "while (!inputFile.eof())" is always the wrong thing to do.

Well, there's also a third problem here:

  1. Using a debugger would've immediately identified both problems. As an example, I loaded the compiled code in a debugger and stepped through it. The issues were readily apparent.
Community
  • 1
  • 1
Sam Varshavchik
  • 84,126
  • 5
  • 57
  • 106
3

@Sam has all the things you did wrong.

But an alternative to using a loop is just to use iterators to build the array.

std::ifstream   file(path);
std::vector<std::string>   words(std::istream_iterator<std::string>(file), 
                                 std::istream_iterator<std::string>());

To print it out you can use copy.

std::copy(std::begin(words), std::end(words),
          std::ostream_iterator(std::cout, "\n"));

Currently this will break words using white space as the separator between words. This means punctuation etc will be included with words. Look here on how to get the streams to treat punctuation as space: How to tokenzie (words) classifying punctuation as space

Community
  • 1
  • 1
Martin York
  • 234,851
  • 74
  • 306
  • 532
0

Thanks to everyone for the help. Here is the final code (for anyone who ends up Googling this in the future)

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <vector>
#include <array>

using namespace std;

int main()

{
string path, test;
ifstream inputFile;
vector<string> words;


cout << "What is the path for the input file? ";

getline(cin, path);

inputFile.open(path, ios::in);


while (inputFile >> test)
{

    words.push_back(test);
}

for (int i = 0; i < words.size(); i++)
{
    cout << words.at(i) << endl;

}

inputFile.close();

return 0;
}
pdsnowden
  • 37
  • 5