1

Ok, so here is the text of the file I am trying to read:

KEYS
a set of keys
3
LAMP
a brightly shining brass lamp
8


ROD
a black rod with a rusty star
12

Ok, so pretend that each line is evenly spaced, but there are 2 blank lines, (or tabs) between 8 and ROD. How would I skip that and continue with the program? I am trying to put each line into 3 vectors (so keys, lamp, and rod into one vector etc). Here is my code (but it does not skip the blank line).:

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

int main() {
    ifstream objFile;
    string inputName;
    string outputName;
    string header;
    cout << "Enter image file name: "; 
    cin >> inputName;
    objFile.open(inputName);
    string name;
    vector<string> name2;
    string description;
    vector<string> description2;
    string initialLocation;
    vector<string> initialLocation2;
    string line;


    if(objFile) {
        while(!objFile.eof()){
                getline(objFile, line);
                name = line;
                name2.push_back(name);
                getline(objFile, line);
                description = line;
                description2.push_back(description);
                getline(objFile, line);
                initialLocation = line;
                initialLocation2.push_back(initialLocation);

             } else {
        cout << "not working" << endl;
    }

    for (std::vector<string>::const_iterator i = name2.begin(); i != name2.end(); ++i)
       std::cout << *i << ' ';
   for (std::vector<string>::const_iterator i = description2.begin(); i != description2.end(); ++i)
       std::cout << *i << ' ';
    for (std::vector<string>::const_iterator i = initialLocation2.begin(); i != initialLocation2.end(); ++i)
        std::cout << *i << ' ';
Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Why not just call `getline` for each blank line? – Kevin Nov 10 '18 at 03:35
  • Because this is actually part of a bigger program that should be able to take in other inputs of the same type with or without blank lines. So I need a way to skip –  Nov 10 '18 at 03:38
  • [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Swordfish Nov 10 '18 at 03:38
  • `for (std::vector::const_iterator i = name2.begin(); i != name2.end(); ++i)` and similar --> `for(auto i{ name2.cbegin() }; i != name2.cend(); ++i)` or `for(auto const & i : name2 )` – Swordfish Nov 10 '18 at 03:41
  • Keep reading lines until you get one that's not empty – Kevin Nov 10 '18 at 03:41

2 Answers2

1

I think you can check to see if the string is empty thru std::getline. If it is, then you can ignore it or something like.

    getline(objFile, line);
    name = line; 
    while(name.length() == 0)
    {
         getline(objFile, line);
         name = line;
    }
    name = line;
    name2.push_back(name);

    getline(objFile, line);
    description= line; 
    while(description.length() == 0)
    {
         getline(objFile, line);
         description = line;
    }
    description= line;
    description2.push_back(description);

    getline(objFile, line);
    initialLocation = line; 
    while(initialLocation.length() == 0)
    {
         getline(objFile, line);
         initialLocation = line;
    }
    initialLocation = line;
    initialLocation2.push_back(initialLocation );

If i am correct then a line will have no length if it is blank and if it is we check again therefore ignoring it.

Ruks
  • 3,886
  • 1
  • 10
  • 22
shiv shah
  • 77
  • 8
  • [`std::basic_string::push_back()`](https://en.cppreference.com/w/cpp/string/basic_string/push_back): "**Appends the given *character* ch to the end of the string.**" – Ruks Nov 10 '18 at 05:17
  • This is good but it only goes through one set then stops at the 3rd line? –  Nov 10 '18 at 06:19
0

You can use std::getline() (As pointed out by many people) instead... which will yield each line one-by-one:

inline std::string ReadFile(std::ifstream& stream)
{
    std::string contents;
    std::string temporary;
    while (std::getline(stream, temporary))
        if (!std::all_of(temporary.begin(), temporary.end(), isspace))
            contents.append(temporary + "\n");
    return contents.substr(0, contents.size() - 1);
}

And yes, an example:

int main()
{
    std::ifstream is("file.txt");
    if (is.fail())
        return 1;
    auto const contents = ReadFile(is);
    is.close();
    std::cout << contents << std::endl;
    std::cin.get();
    return 0;
}
Ruks
  • 3,886
  • 1
  • 10
  • 22