Listy-odczytanie pliku.

0

Po raz kolejny zwracam się do was z prośbą o pomoc. Listy mnie przerastają, a muszę napisać ten program. W teorii ten fragment kodu powinien sczytywać plik textowy do listy. Jednak... tego nie robi.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <malloc.h>


struct LinkedList
{
    int dist;
    char citi_1[10];
    char citi_2[10];
    struct LinkedList* next;
};
struct LinkedList* LinkedList_emplace(char citi1, char citi2, int distance)
{
    struct LinkedList* list = malloc(sizeof(struct LinkedList));
    strcpy(list->citi_1, citi1);
    strcpy(list->citi_2, citi2);
    list->dist = distance;
    list->next = NULL;
    return list;
}
void fill_list(f1)
{
    int distance;
    char city1[10];
    char city2[10];
    bool run_once_more = 1;
    bool complete = 0;
    struct LinkedList* tmp_2;
    int a = 1;
    int z;
    int b = 0;
    char word[10];
    while (!feof(f1) || run_once_more)
    {
        z = 1;
        word[b] = fgetc(f1);
        if (word[b] == ' ' || word[b] == '\n' || word[b] == EOF)
        {
            if (a == 1 && z == 1)
            {
                word[b] = '\0';
                strcpy(city1, word);
                a = 2;
                b = 0;
                z = 0;
            }
            if (a == 2 && z == 1)
            {
                word[b] = '\0';
                strcpy(city2, word);
                a = 3;
                b = 0;
                z = 0;
            }
            if (a == 3 && z == 1)
            {
                word[b] = '\0';
                distance = atoi(word);
                a = 1;
                b = 0;
                z = 0;
                struct LinkedList* tmp_1 = LinkedList_emplace(city1, city2, distance);
                tmp_2->next = tmp_1;
                struct LinkedList* tmp_2 = tmp_1;
                complete = 1;
            }
        }
        if (complete)
        {
            complete = 0;
        }
        if (z == 1)
        {
            b++;
        }
        if (feof(f1))
        {
            run_once_more = 0;
        }
    }
}
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");
}
int main(int argc, char** argv)
{
    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;
    }
    fill_list(*f1);
    fclose(f1);
    fclose(f2);
    fclose(f3);
    return 0;
}

 

Każda linijka pliku tekstowego zawiera 2 słowa i liczbę które osobno powinny zostać zapisane do listy. Czy ktoś mógł by mi z tym pomóc, z góry dziękuję.

1
  1. Kompilator wskazuje ci kolejne błędy.
  2. Zapoznaj się z fscanf()
while(fscanf(f1," %s %s %d",city1,city2,&distance)==3) /* dopuki mamy kolejne dane */
  1. Masz tu poprawne wczytywanie do dobrej struktury:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct cityNode;
typedef struct edgeNode { struct edgeNode *next; struct cityNode *distanation; double distance; } edgeNode;
typedef struct cityNode { edgeNode *head; struct cityNode *next; char name[1]; } cityNode;
typedef struct { cityNode *head; } cityList;
 
edgeNode *allocEdgeNode(cityNode *distanation,double distance,edgeNode *next)
  {
   edgeNode *tmp;
   tmp=(edgeNode *)malloc(sizeof(edgeNode));
   tmp->distanation=distanation;
   tmp->distance=distance;
   tmp->next=next;
   return tmp;
  }
 
void appendEdgeNode(cityNode *src,cityNode *dst,double distance)
  {
   src->head=allocEdgeNode(dst,distance,src->head);
   dst->head=allocEdgeNode(src,distance,dst->head); // usunąć jeżeli graf skierowany
  }
 
cityNode *allocCityNode(const char *name,cityNode *next)
  {
   cityNode *tmp;
   tmp=(cityNode*)malloc(sizeof(cityNode)+strlen(name));
   strcpy(tmp->name,name);
   tmp->next=next;
   tmp->head=NULL;
   return tmp;
  }
 
cityNode *findCityNode(cityList *lst,const char *name)
  {
   cityNode *tmp;
   for(tmp=lst->head;tmp;tmp=tmp->next) if(!strcmp(name,tmp->name)) return tmp;
   return NULL;
  }
 
cityNode *getCityNode(cityList *lst,const char *name)
  {
   cityNode *tmp;
   tmp=findCityNode(lst,name);
   if(tmp) return tmp;
   return lst->head=allocCityNode(name,lst->head);
  }
 
void readGraphFile(cityList *lst,FILE *fd)
  {
   char src[65],dst[65];
   double distance;
   while(fscanf(fd," %64s %64s %lg",src,dst,&distance)==3)
     {
      appendEdgeNode(getCityNode(lst,src),getCityNode(lst,dst),distance);
     }
  }
  
int main()
  {
   cityList lst={NULL};
   cityNode *city;
   edgeNode *edge;
   FILE *fd;
   fd=fopen("graph.txt","r");
   readGraphFile(&lst,fd);
   for(city=lst.head;city;city=city->next)
     {
      printf("%s\n",city->name);
      for(edge=city->head;edge;edge=edge->next)
        {
         printf("\t%s %lg\n",edge->distanation->name,edge->distance);
        }
     }
   fclose(fd);
   return 0;
  }
0

Dziękuję za twoją pomoc. Udało mi się już sczytać te pliki.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <malloc.h>

struct data {
    int dist;
    char citi_1[15];
    char citi_2[15];
  struct data *next;
}*start_d=NULL;
struct search {
    char begin[15];
    char stop[15];
  struct search *next;
}*start_s=NULL;
struct data *fill_list_data(FILE *f1)
{
    struct data *new_data,*current;
    int distance;
    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;
    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_d;
}
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");
}
void display()
{
    struct data *new_data;
    struct search *new_search;
    new_data=start_d;
    while(new_data!=NULL)
    {
        printf("%s--->",new_data->citi_1);
        printf("%s ",new_data->citi_2);
        printf("%d\n",new_data->dist);

        new_data=new_data->next;
    }
    printf("NULL\n");
    new_search=start_s;
    while(new_search!=NULL)
    {
        printf("%s--->",new_search->begin);
        printf("%s\n",new_search->stop);

        new_search=new_search->next;
    }
    printf("NULL\n");
}
void search_route(FILE *f3)
{
    
}
int main(int argc, char** argv)
{

    struct data *start_d;
    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;
    }
    fill_list_data(f1);
    fill_list_search(f2);
    search_route(f3)
    display();
    fclose(f1);
    fclose(f2);
    fclose(f3);
    return 0;
}
 

Pozostał jeszcze problem znalezienia najkrótszej drogi między dwoma miastami. Jeśli masz jakieś rady to był by bardzo wdzięczny :D

0
maksb1 napisał(a):

... Pozostał jeszcze problem znalezienia najkrótszej drogi między dwoma miastami. Jeśli masz jakieś rady to był by bardzo wdzięczny :D
Przy takiej strukturze danych?! Życzę miłego pergolenia (https://pl.wikipedia.org/wiki/Pergola) się.

0

takie dostałem polecenie od osoby prowadzącej laboratoria, żeby to na listach zrobić (jeżeli dobrze zrozumiałem, że tu leży problem). Tak z ciekawości. Jak ty byś to zrobił?

0

To co ja podałem wciąż jest na listach.

0

Problem polega na tym, że napisanie takiego sczytywania jak twoje mnie zwyczajnie przerasta.

0
maksb1 napisał(a):

... napisanie takiego sczytywania jak twoje mnie zwyczajnie przerasta.
Ciekawe w czym to ciebie przerasta? W sumie koncepcja prostsza, nie używane nic poza tym co ty używasz. Zaś kod algorytmu dijkstry będzie jakieś 4-5 razy krótszy.

0

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;
}
0
maksb1 napisał(a):

Zdaję sobie sprawę z tego, że mój kod nie jest najwyższej jakości ...
Może nie zdajesz sobie sprawy że prawdopodobnie zabraknie chętnych babrania się w tym ... (brak mi słów). Więc może zadawaj pytania bardziej konkretnie z małym kodem - przykładem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1