Search code examples
c++c++11substringgetline

C++ How to get substring from ifstream and getline()


What is printed to the console:

START(0,0)
GOAL(0,2)
ooox
xxoo
ooox

I want to be able to obtain the substring of the START and GOAL points, not including the brackets just the coordinate pair. I would also want to store them as variables as well since I want to add validation whether the START or GOAL points are out of bounds from the grid.

I am trying to make an application to traverse the 2D grid, where the 'x' represents the blocked paths and 'o' represents unblocked.

The starting point is always from the bottom left of the grid as represented below:

(0,2)(1,2)(2,2)(3,2)
(0,1)(1,1)(2,1)(3,1)
(0,0)(1,0)(2,0)(3,0)

I have tried using .substr() method with the start and end points of where I would like to store the values but it does not print out anything in the console.

void Grid::loadFromFile(const std::string& filename){
    std::string line;
    std::ifstream file(filename);
    file.open(filename);
    // Reads the file line by line and outputs each line
    while(std::getline(file, line)) {
        std::cout << line << std::endl;
    }

        std::string startPoint, goalPoint;

        startPoint = line.substr(6,3);
        std::cout << startPoint << std::endl;

        file.close();
    }

I expect std::cout << startPoint << std::endl; to print the substring into the console but it just reads the file and prints whatever is in it, and nothing else.


Solution

  • The problem is you are reading ALL lines of the file first, THEN you are parsing only the last line that was read, asking for a starting index that is out of range.

    You need to move your parsing inside the reading loop instead:

    void Grid::loadFromFile(const std::string& filename)
    {
        std::ifstream file(filename);
        if (!file.is_open()) return;
    
        std::string line, startPoint, goalPoint;
        std::vector<std::string> grid;
    
        while (std::getline(file, line))
        {
            if (line.compare(0, 5, "START") == 0)
                startPoint = line.substr(6,3);
            else if (line.compare(0, 4, "GOAL") == 0)
                goalPoint = line.substr(5,3);
            else
                grid.push_back(line);
        }
    
        file.close();
    
        std::cout << startPoint << std::endl;
        std::cout << goalPoint << std::endl;
    
        // process grid as needed...
    }
    

    Or, if you know the 1st two lines are ALWAYS START and GOAL:

    void Grid::loadFromFile(const std::string& filename)
    {
        std::ifstream file(filename);
        if (!file.is_open()) return;
    
        std::string line, startPoint, goalPoint;
        std::vector<std::string> grid;
    
        if (!std::getline(file, line)) return;
        if (line.compare(0, 5, "START") != 0) return;
        startPoint = line.substr(6,3);
    
        if (!std::getline(file, line)) return;
        if (line.compare(0, 4, "GOAL") != 0) return;
        goalPoint = line.substr(5,3);
    
        while (std::getline(file, line))
            grid.push_back(line);
    
        file.close();
    
        std::cout << startPoint << std::endl;
        std::cout << goalPoint << std::endl;
    
        // process grid as needed...
    }