### Instruction:
Write a C++ program that calculates the shortest path between two nodes in a weighted graph using Dijkstra's algorithm. The program should read the graph data from a file and output the shortest path along with its total weight. Additionally, the program should support command line arguments for specifying the input file and source and destination nodes.


### Response:

Here's a C++ program that implements Dijkstra's algorithm to find the shortest path between two nodes in a weighted graph. The program reads the graph data from a file and outputs the shortest path along with its total weight. It also supports command line arguments for specifying the input file and source and destination nodes.

```cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <limits>
#include <string>

using namespace std;

typedef pair<int, int> iPair;

class Graph {
    int V;
    vector<vector<iPair>> adj;

public:
    Graph(int V);
    void addEdge(int u, int v, int w);
    void dijkstra(int src, int dest);
};

Graph::Graph(int V) {
    this->V = V;
    adj.resize(V);
}

void Graph::addEdge(int u, int v, int w) {
    adj[u].push_back(make_pair(v, w));
    adj[v].push_back(make_pair(u, w));
}

void Graph::dijkstra(int src, int dest) {
    priority_queue<iPair, vector<iPair>, greater<iPair>> pq;
    vector<int> dist(V, numeric_limits<int>::max());
    vector<int> parent(V, -1);

    pq.push(make_pair(0, src));
    dist[src] = 0;

    while (!pq.empty()) {
        int u = pq.top().second;
        pq.pop();

        if (u == dest) break;

        for (auto &i : adj[u]) {
            int v = i.first;
            int weight = i.second;

            if (dist[v] > dist[u] + weight) {
                dist[v] = dist[u] + weight;
                pq.push(make_pair(dist[v], v));
                parent[v] = u;
            }
        }
    }

    if (dist[dest] == numeric_limits<int>::max()) {
        cout << "No path found." << endl;
    } else {
        vector<int> path;
        int v = dest;
        while (v != -1) {
            path.push_back(v);
            v = parent[v];
        }

        cout << "Shortest path: ";
        for (int i = path.size() - 1; i >= 0; --i)
            cout << path[i] << (i > 0 ? " -> " : "");
        cout << "\nTotal weight: " << dist[dest] << endl;
    }
}

void readGraphFromFile(const string &filename, Graph &graph) {
    ifstream file(filename);

    if (!file.is_open()) {
        cerr << "Error opening the input file." << endl;
        exit(1);
    }

    int u, v, w;
    while (file >> u >> v >> w) {
        graph.addEdge(u, v, w);
    }

    file.close();
}

int main(int argc, char *argv[]) {
    if (argc < 4) {
        cerr << "Usage: " << argv[0] << " <input_file> <source_node> <destination_node>" << endl;
        return 1;
    }

    string filename = argv[1];
    int src = stoi(argv[2]);
    int dest = stoi(argv[3]);

    // Assuming the maximum number of nodes in the graph is 100.
    Graph g(100);

    readGraphFromFile(filename, g);
    g.dijkstra(src, dest);

    return 0;
}
```

To compile and run the program:

```sh
g++ dijkstra.cpp -o dijkstra
./dijkstra input.txt 0 5
```

The input file should contain the graph data as follows:

```
0 1 4
0 7 8
1 2 8
1 7 11
2 3 7
2 5 4
2 8 2
3 4 9
3 5 14
4 5 10
5 6 2
6 7 1
6 8 6
7 8 7
```

This will create a graph with the following edges and weights:

```
(0, 1, 4), (0, 7, 8), (1, 2, 8), (1, 7, 11), (2, 3, 7),
(2, 5, 4), (2, 8, 2), (3, 4, 9), (3, 5, 14), (4, 5, 10),
(5, 6, 2), (6, 7, 1), (6, 8, 6), (7, 8, 7)
```