• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

C - Odczyt z pliku kilku numerów i zapis do listy

Object Storage Arubacloud
0 głosów
240 wizyt
pytanie zadane 30 maja 2017 w C i C++ przez NyguseK Użytkownik (650 p.)
edycja 30 maja 2017 przez NyguseK

Witam! Jestem w trakcie pisania bazy kontaktów, mam jednak pewien problem. Nie wiem jak wczytać numery telefonów  z pliku do listy. Tutaj jeden kontakt może mieć ich kilka, ilość jest nieokreślona. Numery w pliku zapisuje po spacji, to jest największą trudnością, bo nie wiem jak całą linijkę podzielić na kilka części i każdą z osobna zapisać do innego elementu listy.

Na początek wstawiam typy bazowe:

 

struct contacts
{
    int ID;
    char name[32];
    char surname[32];
    char city[32];
    char street[32];
    char house_number[32];
    char postal_code[7];
    char post_office[32];
    char email[32];
    struct contacts *next;
};

struct nr_tel
{
    int ID;
    char number[10];
    struct nr_tel *next;
};



Teraz funkcja wczytująca dane z pliku:

 

void load_file(struct contacts **list_pointer, struct nr_tel **phone_pointer){
    int line_counter = -1;
    int id;
    FILE *load = NULL;
    load = fopen("kontakty.txt", "r");
	char buffer[32];
    while (fscanf(load, "%s", buffer) != EOF){
        id = get_next_id();
        struct contacts * new_node = (struct contacts*)malloc(sizeof(struct contacts));
        if(new_node){
            line_counter++;
            switch(line_counter){
                case 0:
                {
                    line_counter ++;

                };
                case 1: {
                    fscanf(load, "%s\n", buffer);
                    strcpy(new_node->name, buffer);

                    line_counter++;
                };
                case 2: {
                    fscanf(load, "%s\n", buffer);
                    strcpy(new_node->surname, buffer);
                    line_counter++;
                };
                case 3: {
                    fscanf(load, "%s\n", buffer);
                    strcpy(new_node->city, buffer);
                    line_counter++;
                };
                case 4: {
                    fscanf(load, "%s\n", buffer);
                    strcpy(new_node->street, buffer);
                    line_counter++;
                };
                case 5: {
                    fscanf(load, "%s\n", buffer);
                    strcpy(new_node->house_number, buffer);
                    line_counter++;

                };
                case 6: {
                    fscanf(load, "%s\n", buffer);
                    strcpy(new_node->postal_code, buffer);

                    line_counter++;
                };
                case 7: {
                   ; // Numer telefonu;
                };

                case 8: {
                    ; // mail
                    }
                };
            }
        }
    fclose(load);
}

Bardzo proszę o pomoc, każda wskazówka będzie cenna :)
Pozdrawiam!

1 odpowiedź

0 głosów
odpowiedź 30 maja 2017 przez tangarr Mędrzec (154,780 p.)

Wszystkie pola twojej struktury są stałej długości. Nie musisz się bawić w żadne dzielenie linii na części.
Użyj pliku binarnego i po prostu zapisuj do niego dane o stałej długości.
 

FILE *plik = fopen("dane.txt", "wb");
fwrite(&kontakt->ID, sizeof(int), 1, plik);
fwrite(kontakt->name, sizeof(char), sizeof(kontakt->name), plik);
fwrite(kontakt->surname, sizeof(char), sizeof(kontakt->surname), plik);
// i tak dalej

Albo możesz skorzystać z faktu, że twoja struktura zajmuje ciągłą pamięć i skrócić zapis jeszcze bardziej.
 

Contact *kontakt = /* inicjalizacja */;
FILE *plik = fopen("dane.txt", "wb");
fwrite(kontakt, sizeof(Contact), 1, plik); 
//uwaga: do pliku zostanie zapisana cała struktura wraz z adresem wskaźnika
Contact *kontakt = (Contact*) malloc(sizeof(Contact));
FILE *plik = fopen("dane.txt", "rb");
fread(kontakt, sizeof(Contact), 1, plik); 
kontakt->next = NULL; // czyścimy śmieciowy wskaźnik

 

komentarz 30 maja 2017 przez NyguseK Użytkownik (650 p.)
Dziękuję bardzo za odpowiedź!
Jednak chyba nie wyraziłem się zbyt jasno :/
Jeżeli chodzi o imię, nazwisko itd.. to nie ma problemu :) Ale jeżeli mam odczytać numery telefonów, których jeden kontakt może mieć jeden, a może i mieć 20 to jest problem niestety. Dlatego chciałem dzielić linię na części.
komentarz 30 maja 2017 przez tangarr Mędrzec (154,780 p.)

Bazowałem jedynie na podstawie twojej struktury.
Jeżeli upierasz się na plik tekstowy to możesz użyć funkcji strtok do podzielenia linii na części.
Jednak upierałbym się na zastosowaniu pliku binarnego.
 

typedef struct nr_tel
{
    char number[10];
    struct nr_tel *next;
} nr_tel_t;

typedef struct contacts
{
    int ID;
    char name[32];
    struct nr_tel *lista_tel;
    struct contacts *next;
} contacts_t;
 
int ilosc_numerow(contacts_t *kontakt) {
    if (!kontakt)
        return 0;
    int ilosc = 0;
    nr_tel_t *tel = kontakt->lista_tel;
    while(tel) {
    ++ilosc;
    tel=tel->next;
    }
}

void zapisz_kontakt(contacts_t *kontakt, FILE *plik) {
    fwrite(&kontakt->ID, sizeof(int), 1, plik);
    int ilosc_tel = ilosc_numerok(kontakt);
    fwrite(&ilosc_tel, sizeof(int), 1, plik);
    nr_tel_t* tel = kontakt->lista_tel;
    while(tel) {
        fwrite(tel->number, sizeof(char), sizeof(tel->number), plik);
        tel = tel->next;
    } 
}

 

komentarz 30 maja 2017 przez tangarr Mędrzec (154,780 p.)
Dodatkowo polecam sprawdzać czy zapis się udał przy pomocy funkcji http://www.cplusplus.com/reference/cstdio/ferror/
komentarz 30 maja 2017 przez NyguseK Użytkownik (650 p.)
Dziękuję bardzo za pomoc! Brakowało mi tej funkcji :D  Już się biorę za pisanie :) Zostanę jednak przy pliku tekstowym, gdyż binarny nie do końca ogarniam :/

Podobne pytania

0 głosów
1 odpowiedź 507 wizyt
pytanie zadane 7 grudnia 2018 w C i C++ przez matiibal Użytkownik (620 p.)
0 głosów
1 odpowiedź 1,829 wizyt
+1 głos
1 odpowiedź 1,285 wizyt

92,555 zapytań

141,403 odpowiedzi

319,554 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...