-2
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

std::ifstream iFile;
std::string string;
std::vector<std::streampos> titlePos;

int main()
{
    iFile.open("presets.txt", std::ios_base::app);
    if (!iFile.is_open())
    {
        std::cout << "iFile presets isnt open" << std::endl;
    }
    while (!iFile.eof())
    {
        iFile >> string;
        if (string == "%title")
        {
            iFile >> string;
            titlePos.emplace_back(iFile.tellg());
        }
    }
    for (int x = titlePos.size() - 1; x != -1; --x)
    {
        iFile.seekg(titlePos[x]);
        std::cout << titlePos[x] << std::endl;
        std::cout << iFile.tellg() << std::endl;
    }
    return 0;
}

For some reason, the cout for listPos[x] are all usual (I think), but once I transfer the streampos values to the ifstream iFile, they all result in a -1 being outputted (an error, I assume).

I do not understand why transferring the values causes an error, or how I would go about finding the cause of the error.

IN "presets.txt"

%title loc1

%title loc2

%title loc3

OUTPUT

-1
-1
26
-1
11
-1
Sean Bird
  • 11
  • 1
  • 4
    Where to the values in `listPos` come from? What are `strings` and `word`? Can we get a [mre]? – 1201ProgramAlarm Jun 13 '21 at 22:32
  • @1201ProgramAlarm the listPos values come from a series of listPos.push_back(iFile.tellg) calls. I will try to make a MRE but im new to this site so it might take a bit. – Sean Bird Jun 13 '21 at 23:08
  • EOF isn't set until an attempt is made to read past the end. The failed `iFile >> string` will also set the stream to a fail state (`fail()` will return true). Once failed, the seeks (and tells) won't work. You need to clear the error state after your EOF loop and before your output loop (with `ifile.clear()`). – 1201ProgramAlarm Jun 14 '21 at 15:15
  • @1201ProgramAlarm i tried that now and it is set back to fail after iFile.seekg(titlePos[x]), but not before – Sean Bird Jun 14 '21 at 16:10
  • [Why is `iostream::eof` inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/q/5605125/12149471) – Andreas Wenzel Jun 14 '21 at 16:52

1 Answers1

0

After a failure (excluding eof) reading data from a stream tellg and seekg will both also fail and return -1.

while (!iFile.eof()) also means you check the stream state before reading values rather than after reading them. You should check whether each operation succeeds before using the value, this is the cause of the last entry in titlePos being -1.

To reset the stream to good you need to call clear().

This should then work:

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

std::ifstream iFile;
std::string string;
std::vector<std::streampos> titlePos;

int main()
{
    iFile.open("presets.txt", std::ios_base::app);
    if (!iFile.is_open())
    {
        std::cout << "iFile presets isnt open" << std::endl;
    }
    while (iFile)
    {
        if (!(iFile >> string))
        {
            break;
        }
        if (string == "%title")
        {
            if (!(iFile >> string))
            {
                std::cout << "error reading string\n";
                break;
            }
            titlePos.emplace_back(iFile.tellg());
        }
    }
    iFile.clear();
    for (int x = titlePos.size() - 1; x != -1; --x)
    {
        iFile.seekg(titlePos[x]);
        std::cout << titlePos[x] << std::endl;
        std::cout << iFile.tellg() << std::endl;
    }
    return 0;
}
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Hi, i tried clearing the iFile before setting its locations, but it still resulted in an error being returned. – Sean Bird Jun 14 '21 at 18:11
  • Instead of `titlePos.clear();`, did you intend to write `iFile.clear();`? – Andreas Wenzel Jun 14 '21 at 19:12
  • It seems to me that you are confusing `titlePos` and `iFile`. The line `titlePos.seekg(titlePos[x]);` does not make sense, as `titlePos`, which is a `std::vector`, does not have a member `seekg`. I believe it was correct before you changed it in your most recent edit. – Andreas Wenzel Jun 14 '21 at 20:31