This C-language program is designed to analyze weighted directed graphs from text files.
It automates the following tasks:
- Searching for all text files (
.txt) present in the current directory. - Allowing the user to interactively choose a file.
- Reading multiple graphs contained in the selected file (a single file may contain several graphs consecutively).
- Storing each graph in memory using an adjacency matrix representation.
- Displaying all available graphs and allowing the user to select a specific graph.
- Applying the Floyd-Warshall algorithm to the chosen graph:
- computing the shortest paths between every pair of vertices,
- displaying intermediate matrices at each step of the algorithm (L and P matrices),
- detecting possible negative cycles (absorbing circuits).
- If no negative cycle exists:
- interactive interface allowing the user to request the shortest path between two chosen vertices,
- displaying the minimal path length,
- reconstructing the actual path (sequence of visited vertices).
- Allowing the processing of multiple graphs successively without exiting the program.
This program is intended for beginner C programmers and demonstrates:
- the use of standard C libraries,
- text file manipulation,
- dynamic memory allocation,
- handling two-dimensional arrays (matrices),
- implementation of a classic graph theory algorithm (Floyd-Warshall).
The program uses several standard C libraries.
Standard input/output library. It provides:
| Function | Description |
|---|---|
printf |
Formatted output to the standard output (terminal) |
scanf |
Formatted input from the standard input (keyboard) |
FILE |
Type representing an opened file |
fopen |
Opens a file |
fclose |
Closes an opened file |
fscanf |
Formatted reading from a file |
Standard utility library. It provides:
| Function | Description |
|---|---|
malloc |
Dynamic memory allocation (heap allocation) |
free |
Frees memory previously allocated with malloc |
In this program, malloc and free are used to:
- allocate graph adjacency matrices,
- allocate the L and P matrices of the Floyd-Warshall algorithm,
- allocate
Graphstructures, - allocate character strings for file names.
This library introduces:
| Element | Description |
|---|---|
bool |
Boolean type |
true |
Equivalent to 1 |
false |
Equivalent to 0 |
In the program, this type is used for logical variables such as readError in the chooseGraph function.
String handling library. It provides:
| Function | Description |
|---|---|
strlen |
Length of a string |
strcmp |
Compares two strings (returns 0 if identical) |
strcpy |
Copies a string into another |
These functions are used in isTxt and chooseTxt.
Directory manipulation library. It provides:
| Element | Description |
|---|---|
DIR |
Type representing an opened directory |
struct dirent |
Structure representing a directory entry |
opendir |
Opens a directory |
readdir |
Reads directory entries successively |
closedir |
Closes a directory |
Library providing constants related to integer limits (INT_MAX, INT_MIN, etc.).
Used to define a "pseudo-infinity" value:
#define INFINITY (INT_MAX / 4)Note:
INT_MAX / 4is used instead ofINT_MAXto avoid overflow when adding distances.
#define MAX_FILES 100
#define MAX_LENGTH 256
#define MAX_GRAPHS 100
#define INFINITY (INT_MAX / 4)| Macro | Description |
|---|---|
MAX_FILES |
Maximum number of .txt files to list |
MAX_LENGTH |
Maximum buffer size for reading lines |
MAX_GRAPHS |
Maximum number of graphs stored in memory |
INFINITY |
Value representing "no path" or "infinite distance" |
typedef struct {
int nbVertices;
int **adjMat;
} Graph;| Field | Description |
|---|---|
nbVertices |
Number of graph vertices (numbered from 0 to n-1) |
adjMat |
n × n adjacency matrix |
The adjacency matrix adjMat is represented as an array of pointers (int**):
adjMat[i][j]contains the weight of the edge fromitoj- If no direct edge exists, the value is initially
0, then replaced byINFINITYin working matrices
Purpose: Determine whether a string name ends with the .txt extension.
Algorithm:
- Compute the length using
strlen(name) - If length < 4, return 0
- Compare the last 4 characters to
.txtusingstrcmp - Return 1 if matching, otherwise 0
Purpose:
- List all
.txtfiles in the current directory - Allow the user to choose one
- Return the selected file name (dynamically allocated)
Algorithm:
- Open the current directory with
opendir(".") - Iterate through entries using
readdir(dir) - Filter entries with
isTxt() - Display the list and ask for user selection
- Return the chosen file name (must later be freed with
free)
Purpose: Allocate and free square integer matrices of size n × n.
allocateMatrix:
int** allocateMatrix(int n) {
int** m = malloc(n * sizeof(int*));
for (int i = 0; i < n; i++) {
m[i] = malloc(n * sizeof(int));
for (int j = 0; j < n; j++) {
m[i][j] = 0;
}
}
return m;
}freeMatrix:
void freeMatrix(int **m, int n) {
for (int i = 0; i < n; i++) {
free(m[i]);
}
free(m);
}Purpose: Display an integer matrix neatly.
Display format:
- Header row with column indices
- Each cell displays either the integer value or
.if equal toINFINITY
Purpose:
- Read multiple graphs from a file
- Store and display them
- Let the user choose one graph
- Return the selected graph
Detailed Algorithm:
- Open the file with
fopen(fileName, "r") - For each graph:
- Read
n(number of vertices) andm(number of edges) - Allocate the graph and its adjacency matrix
- Read the
medges (u v w)
- Read
- Display all available graphs
- Ask for user selection
- Free all unselected graphs
- Return the chosen graph
Purpose: Display the shortest path from u to v using matrix P.
Algorithm:
- If
P[u][v] == -1, no path exists - Otherwise, follow successors until reaching
v
Purpose: Apply the Floyd-Warshall algorithm to the graph and interactively display shortest paths.
Algorithm:
-
Initialize matrices L and P:
L[i][j] = 0ifi == jL[i][j] = weightif a direct edge existsL[i][j] = INFINITYotherwiseP[i][j] = jif a direct edge exists, otherwise-1
-
Main loop:
For each intermediate vertex k from 0 to n-1: For each pair (i, j): If L[i][k] + L[k][j] < L[i][j]: L[i][j] = L[i][k] + L[k][j] P[i][j] = P[i][k] -
Negative cycle detection:
- If
L[i][i] < 0for some vertexi, a negative cycle exists
- If
-
User interface:
- If no negative cycle exists, allow shortest path queries
Purpose: Coordinate the execution of the program.
Main loop:
- Call
chooseTxt()to select a file - Call
chooseGraph(file)to select a graph - Call
floydWarshall(g)to analyze it - Free allocated resources
- Ask whether to process another graph
For each graph:
n
m
u1 v1 w1
u2 v2 w2
...
um vm wm
| Element | Description |
|---|---|
n |
Number of vertices (numbered from 0 to n-1) |
m |
Number of edges |
ui vi wi |
Directed edge from ui to vi with weight wi |
Example:
3
3
0 1 4
1 2 5
0 2 10
4
4
0 1 1
1 2 2
2 3 3
0 3 10
This file contains two graphs: the first with 3 vertices and the second with 4 vertices.
This program demonstrates how to:
- ✅ Manipulate files and directories in C
- ✅ Structure data using
struct Graphand matrices - ✅ Implement a non-trivial algorithm (Floyd-Warshall)
- ✅ Manage dynamic memory allocation and deallocation correctly
- ✅ Interact with the user through the console
| Function | Purpose |
|---|---|
isTxt |
Filter file names |
chooseTxt |
Select a graph file |
allocateMatrix / freeMatrix |
Manage matrices |
displayMatrix |
Display matrices |
chooseGraph |
Read, store, display, and choose a graph |
floydWarshall |
Core algorithm (shortest paths + cycle detection) |
displayPath |
Reconstruct shortest paths |
main |
Coordinate the entire program |