Zdaję sobie sprawę z tego, że mój kod nie jest najwyższej jakości, ale działa. Muszę jeszcze zrobić tak, żeby chary w listach były rozmiarów kopiowanych do nich słów. Wiesz może jak coś takiego zrobić? realloc?
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <malloc.h>
#include <string.h>
#define MAX_INT 10000000
struct city
{
char citi[15];
struct city* next;
};
struct data
{
int dist;
char citi_1[15];
char citi_2[15];
struct data* next;
};
struct search
{
char begin[15];
char stop[15];
struct search* next;
};
struct data* fill_list_data(FILE* f1)
{
struct data *new_data, *current, *start_d = NULL;
int distance;
int i = 0;
int x = 0;
char* pointer;
char city1[15];
char city2[15];
while (!feof(f1))
{
fscanf(f1, " %s %s %d", city1, city2, &distance);
new_data = (struct data*)malloc(sizeof(struct data));
strcpy(new_data->citi_1, city1);
strcpy(new_data->citi_2, city2);
new_data->dist = distance;
new_data->next = NULL;
if (start_d == NULL)
{
start_d = new_data;
current = new_data;
}
else
{
current->next = new_data;
current = new_data;
}
}
return start_d;
}
struct search* fill_list_search(FILE* f2)
{
struct search *new_data, *current, *start_s = NULL;
int distance;
char city1[15];
char city2[15];
while (!feof(f2))
{
fscanf(f2, " %s %s", city1, city2);
new_data = (struct search*)malloc(sizeof(struct search));
strcpy(new_data->begin, city1);
strcpy(new_data->stop, city2);
new_data->next = NULL;
if (start_s == NULL)
{
start_s = new_data;
current = new_data;
}
else
{
current->next = new_data;
current = new_data;
}
}
return start_s;
}
void help() /*function printing instructions in case of errors*/
{
printf("==================================================================\n");
printf(" Instruction\n");
printf(" The program should run from console with following\n");
printf("parameters: program.exe -d input1.txt -t input2.txt -o output.txt.\n");
printf("==================================================================\n");
}
struct city* city_list(struct data* start_d)
{
bool exist_1 = 0, exist_2 = 0;
struct city *new_data, *current_check, *current, *start_c = NULL;
struct data* current_1 = start_d;
bool first = 0;
bool one_more = 1;
while (current_1->next != NULL || one_more)
{
if (first)
{
while (current_check->next != NULL || one_more)
{
if (strcmp(current_1->citi_1, current_check->citi) == 0)
{
exist_1 = 1;
}
if (strcmp(current_1->citi_2, current_check->citi) == 0)
{
exist_2 = 1;
}
if (current_check->next == NULL)
{
one_more = 0;
}
else
{
current_check = current_check->next;
}
}
}
one_more = 1;
if (!exist_1)
{
first = 1;
new_data = (struct city*)malloc(sizeof(struct city));
strcpy(new_data->citi, current_1->citi_1);
new_data->next = NULL;
if (start_c == NULL)
{
start_c = new_data;
current = new_data;
}
else
{
current->next = new_data;
current = new_data;
}
}
if (!exist_2)
{
first = 1;
new_data = (struct city*)malloc(sizeof(struct city));
strcpy(new_data->citi, current_1->citi_2);
new_data->next = NULL;
if (start_c == NULL)
{
start_c = new_data;
current = new_data;
}
else
{
current->next = new_data;
current = new_data;
}
}
current_check = start_c;
exist_1 = 0;
exist_2 = 0;
if (current_1->next == NULL)
{
one_more = 0;
}
else
{
current_1 = current_1->next;
}
}
return start_c;
}
int counter(struct city* start_c)
{
int x = 0;
bool one_more = 1;
struct city* current = start_c;
while (current->next != NULL || one_more)
{
x++;
if (current->next == NULL)
{
one_more = 0;
}
else
{
current = current->next;
}
}
return x;
}
int fill_matrix(int j, int k, struct city* start_c, struct data* start_d)
{
struct city* current = start_c;
int x = 0;
int y = 0;
char adress_1[15];
char adress_2[15];
bool one_more = 1;
if (j == k)
{
return 0;
}
else
{
while (x != j)
{
current = current->next;
x++;
}
strcpy(adress_1, current->citi);
current = start_c;
while (y != k)
{
current = current->next;
y++;
}
strcpy(adress_2, current->citi);
struct data* current_1 = start_d;
while (current_1->next != NULL || one_more)
{
if (strcmp(current_1->citi_1, adress_1) == 0
&& strcmp(current_1->citi_2, adress_2) == 0)
{
return current_1->dist;
}
if (current_1->next == NULL)
{
one_more = 0;
}
else
{
current_1 = current_1->next;
}
}
return MAX_INT;
}
}
void finder(int* j, int* k, struct city* start_c, struct search* current)
{
int p = 0, l = 0;
bool found_1 = 0, found_2 = 0, one_more = 1;
struct city* current_1 = start_c;
while (current_1->next != NULL || one_more)
{
if (found_1 && found_2)
{
break;
}
if (strcmp(current->begin, current_1->citi) == 0)
{
found_1 = 1;
}
if (!found_1)
{
p++;
}
if (strcmp(current->stop, current_1->citi) == 0)
{
found_2 = 1;
}
if (!found_2)
{
l++;
}
if (current_1->next == NULL)
{
one_more = 0;
}
else
{
current_1 = current_1->next;
}
}
*j = p;
*k = l;
}
void find_route(int x, FILE* f3, struct city* start_c, struct data* start_d, struct search* start_s)
{
int j = 0, k = 0, r = 0, q, g;
struct search* current = start_s;
bool one_more = 1;
int d[x];
int p[x];
int matrix[x][x];
while (j < x)
{
while (k < x)
{
matrix[j][k] = fill_matrix(j, k, start_c, start_d);
k++;
}
k = 0;
j++;
}
j = 0;
k = 0;
while (current->next != NULL || one_more)
{
finder(&j, &k, start_c, current);
if (j == x || k == x)
{
print_error(current->begin, current->stop, f3);
}
else
{
one_more = 1;
while (r < x)
{
d[r] = MAX_INT;
p[r] = -1;
r++;
}
r = 0;
int i = 0;
int z = 0;
d[j] = 0;
p[j] = j;
while (one_more)
{
one_more = 0;
while (i < x)
{
while (z < x)
{
if (d[i] > d[z] + matrix[z][i])
{
one_more = 1;
d[i] = d[z] + matrix[z][i];
p[i] = z;
}
z++;
}
z = 0;
i++;
}
i = 0;
}
if (d[k] == MAX_INT)
{
print_error(current->begin, current->stop, f3);
}
else
{
print_road(j, k, f3, d, p, start_c, current->begin, current->stop);
}
}
one_more = 1;
if (current->next == NULL)
{
one_more = 0;
}
else
{
current = current->next;
}
j = 0;
k = 0;
}
}
void print_road(
int j, int k, FILE* f3, int d[], int p[], struct city* start_c, char start[15], char stop[15])
{
int q = j;
int g = k;
int prev;
int m = 0, n = 0;
struct city* current_1 = start_c;
fprintf(f3, "trasa: %s --> %s (%d):\n", start, stop, d[k]);
while (q != k)
{
prev = d[q];
while (p[g] != q)
{
g = p[g];
}
while (m < q)
{
current_1 = current_1->next;
m++;
}
strcpy(start, current_1->citi);
current_1 = start_c;
while (n < g)
{
current_1 = current_1->next;
n++;
}
strcpy(stop, current_1->citi);
current_1 = start_c;
fprintf(f3, " %s --> %s %d\n", start, stop, d[g] - prev);
n = 0;
m = 0;
q = g;
g = k;
}
}
void print_error(char start[15], char stop[15], FILE* f3)
{
fprintf(f3, "trasa: %s --> %s\n", start, stop);
fprintf(f3, " TRASA NIEMOZLIWA DO WYLICZENIA\n");
}
void free_memory(struct data* start_d, struct search* start_s, struct city* start_c)
{
bool one_more = 1;
struct city* current_1 = start_c;
struct data* current_2 = start_d;
struct search* current_3 = start_s;
struct city* temp_1;
struct data* temp_2;
struct search* temp_3;
while (current_1->next != NULL || one_more)
{
temp_1 = current_1;
current_1 = current_1->next;
free(temp_1);
if (current_1->next == NULL)
{
one_more = 0;
}
}
while (current_2->next != NULL || one_more)
{
temp_2 = current_2;
current_2 = current_2->next;
free(temp_2);
if (current_2->next == NULL)
{
one_more = 0;
}
}
while (current_3->next != NULL || one_more)
{
temp_3 = current_3;
current_3 = current_3->next;
free(temp_3);
if (current_3->next == NULL)
{
one_more = 0;
}
}
}
int main(int argc, char** argv)
{
struct city* start_c = NULL;
struct search* start_s = NULL;
struct data* start_d = NULL;
int x;
int i;
FILE* f1;
FILE* f2;
FILE* f3;
for (i = 0; i < argc; i++) /*loop opening proper arguments*/
{
if (strcmp(argv[i], "-d") == 0)
{
f1 = fopen(argv[i + 1], "r");
}
if (strcmp(argv[i], "-t") == 0)
{
f2 = fopen(argv[i + 1], "r");
}
if (strcmp(argv[i], "-o") == 0)
{
f3 = fopen(argv[i + 1], "w");
}
if (strcmp(argv[i], "-h") == 0)
{
help();
}
}
if (f1 == NULL || f2 == NULL || f3 == NULL)
{
help();
return;
}
start_d = fill_list_data(f1);
start_s = fill_list_search(f2);
start_c = city_list(start_d);
x = counter(start_c);
find_route(x, f3, start_c, start_d, start_s);
free_memory(start_d, start_s, start_c);
fclose(f1);
fclose(f2);
fclose(f3);
return 0;
}