If you run this program, you'll see that it works fine, but the only problem I have is that my Manhattan Distance is occasionally wrong. My equation seems to be fine, and I don't have a debugger in VS Code, so I am having extreme difficulty diagnosing this problem. My Manhattan Distance calculation seems to be silently breaking whenever it wants to, and it's confusing me.
Source code:
#include <iostream> 
#include <fstream>
#include <cstdlib> //For std::exit()
#include <vector>
#include <cmath>
#include <iomanip>
struct dataPoint {
    int x1; 
    int y1;
    std::string name;
}; 
struct queryPoint {
    int x2; 
    int y2; 
    std::string name;
};
class File
{
public: 
    File(std::string dataFile, std::string queryFile)
        : m_dataFile{ dataFile }, m_queryFile{ queryFile }
    {
        m_dataPoints.reserve(50); 
        m_queryPoints.reserve(50);
    }
    //Constructor to initalize class object. 
    void errorDataCheck() {
        std::ifstream infile; 
        infile.open(m_dataFile); 
        if(!infile.is_open()) {
            std::cout << "Error: Unable to open the data file\n"; 
            infile.close(); //Close file before exiting to prevent corruption.
            std::exit(3);
        } //std::exit is okay to use here, since we don't risk corruption.
        infile.close(); 
    }
    void errorQueryCheck() {
        std::ifstream infile; 
        infile.open(m_queryFile); 
        if(!infile.is_open()) {
            std::cout << "Error: Unable to open the query file\n";
            infile.close(); 
            std::exit(3);
        }
        infile.close();
    }
    void errorCheck() {
        errorDataCheck();
        errorQueryCheck();
    }
    void const readFile() {
        std::ifstream dataInfile; 
        dataInfile.open(m_dataFile);
        bool data1{ false }; 
        bool data2{ false }; 
        bool query1{ false }; 
        bool query2{ false };
        while( !dataInfile.eof() ) {
            dataPoint dataPoint;
            dataInfile >> dataPoint.x1; 
            dataInfile >> dataPoint.y1; 
            dataInfile >> dataPoint.name;
            m_dataPoints.push_back(dataPoint);
        }
        dataInfile.close();
        std::ifstream queryInfile; 
        queryInfile.open(m_queryFile);
        while( !queryInfile.eof() ) {
            queryPoint point;
            queryInfile >> point.x2; 
            queryInfile >> point.y2; 
            queryInfile >> point.name;
            if(data1 || data2 || query1 || query2) {
                if(data1) std::cout << "Invalid point in data file\n"; 
                if(data2) std::cout << "Invalid point in data file\n"; 
                if(query1) std::cout << "Invalid point in query file\n"; 
                if(query2) std::cout << "Invalid point in query file\n";
                std::exit(3);
            }
            m_queryPoints.push_back(point);
        }
        queryInfile.close();
    }
    void sendFile() {
        std::ofstream outfile;
        for(auto& dataElement : m_dataPoints) {
            if(dataElement.name == m_dataPoints[m_dataPoints.size()].name) //Discard final element in vector because it's garbage. Tbh I don't even know how it got there. 
                break; 
            std::string fileName{"Distances_" + dataElement.name};
            outfile.open(fileName);
            outfile << "x1 y1 label\n"; 
            outfile << dataElement.x1 << ' ' << dataElement.y1 << ' ' << dataElement.name << '\n';
            outfile << "x2 y2 manDist eucDist label\n";
            for(auto& queryElement : m_queryPoints) {
                if(queryElement.name == m_queryPoints[m_queryPoints.size()].name)
                    break;
                outfile << queryElement.x2 << ' ' << queryElement.y2 << ' ';
                outfile << std::setprecision(4) << abs( (dataElement.x1 - queryElement.x2) + (dataElement.y1 - queryElement.y2) ) << ' ';
                outfile << std::setprecision(4) << sqrt( pow(dataElement.x1 - queryElement.x2, 2) + pow(dataElement.y1 - queryElement.y2, 2) ) << ' ';
                outfile << queryElement.name << '\n';
            }
            outfile.close();
        }
    }
    void print() {
        for(auto& element : m_dataPoints)
            std::cout << element.x1 << ' ' << element.y1 << ' ' << element.name << '\n';
        for(auto& element : m_queryPoints)
            std::cout << element.x2 << ' ' << element.y2 << ' ' << element.name << '\n'; 
    }
private: 
    std::string m_dataFile; 
    std::string m_queryFile;
    std::vector<dataPoint> m_dataPoints; 
    std::vector<queryPoint> m_queryPoints;
};
void errorArgcCheck(int argc)
{
    if(argc == 1) {
        std::cout << "Usage: ./a.out dataFile queryFile\n"; 
        std::exit(1);
    }
    else if(argc != 3) {
        std::cout << "Error: Incorrect amount of command line arguments\n"; 
        std::exit(1);
    }
} //Has to be done outside class before we can initialize object.
int main(int argc, char* argv[])
{
    errorArgcCheck(argc); //Check argv[1] and argv[2] for existence before initialize File object.
    File files{argv[1], argv[2]}; //Initialize class object with file names and argc
    files.errorCheck(); //Computationally expensive to open and close files, but doesn't matter for a 100-200 line program.
    files.readFile(); 
    files.sendFile();
    files.print();
    std::cout << '\n';
    return 0;
}
Data file:
-1200 300 Plane_001
-1100 500 Plane_002
-800 200 Plane_003
-400 600 Plane_004
-1100 -100 Plane_005
-800 -400 Plane_006
-500 -600 Plane_007
200 100 Plane_008
300 800 Plane_009
700 100 Plane_010
900 400 Plane_011
400 -600 Plane_012
800 -800 Plane_013
1000 -300 Plane_014
Query File:
-1300 100 SFO
-1200 700 SEA
-900 500 JAC
-600 100 SLC
-200 700 MSP
-200 300 JAC
-1200 -300 LAX
-700 -200 LAS
-300 -100 DEN
-400 -500 PHX
0 -300 DFW
100 500 ORD
300 500 DTW
700 700 EWR
900 700 JFK
900 100 CLT
300 -100 STL
500 -400 ATL
900 -600 MCO
1000 -800 MIA
Desired output for distance_plane_001 file:
x1 y1 label
-1200 300 Plane_001
x2 y2 manDist eucDist label
-1300 100 300 223.6 SFO
-1200 700 400 400 SEA
-900 500 500 360.6 JAC
-600 100 800 632.5 SLC
-200 700 1400 1077 MSP
-200 300 1000 1000 JAC
-1200 -300 600 600 LAX
-700 -200 1000 707.1 LAS
-300 -100 1300 984.9 DEN
-400 -500 1600 1131 PHX
0 -300 1800 1342 DFW
100 500 1500 1315 ORD
300 500 1700 1513 DTW
700 700 2300 1942 EWR
900 700 2500 2138 JFK
900 100 2300 2110 CLT
300 -100 1900 1552 STL
500 -400 2400 1838 ATL
900 -600 3000 2285 MCO
1000 -800 3300 2460 MIA
The program output for plane_001:
x1 y1 label
-1200 300 Plane_001
x2 y2 manDist eucDist label
-1300 100 300 223.6 SFO
-1200 700 400 400 SEA
-900 500 500 360.6 JAC
-600 100 400 632.5 SLC
-200 700 1400 1077 MSP
-200 300 1000 1000 JAC
-1200 -300 600 600 LAX
-700 -200 0 707.1 LAS
-300 -100 500 984.9 DEN
-400 -500 0 1131 PHX
0 -300 600 1342 DFW
100 500 1500 1315 ORD
300 500 1700 1513 DTW
700 700 2300 1942 EWR
900 700 2500 2138 JFK
900 100 1900 2110 CLT
300 -100 1100 1552 STL
500 -400 1000 1838 ATL
900 -600 1200 2285 MCO
1000 -800 1100 2460 MIA
 
    