Artefakty przy wczytywaniu danych z pliku.

0

Moim celem jest stworzenie listy dwukierunkowej, która reprezentuje książkę adresową. Dane mają być wczytywane z pliku. Niestety niewiedzieć czemu powstają mi artefakty. Co ciekawe, jak się dobrze przyjrzeć, to litery wczytywane są dobrze, tylko pojawiają się między nimi znaczki. Nie wiem czy to problem alokacji pamięci, czy też partacko zrobionego pobierania danych. Z góry dzięki za pomoc. Oto kod:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>

/////////////////////////////////////////////////////////

typedef struct dane
{
	char nazwisko[100];
	char imie[100];

	char miasto[100];
	char ulica[100];
	int numer;
	char dodatek;
	int mieszkania;

	char kod_pocztowy[7];
	long telefon;
	
	struct dane *next, *prev;
	
} kontakt;

/////////////////////////////////////////////////////////

void pobierz_liste(kontakt **poczatek , kontakt **koniec , int *rekordy);
void wyswietl_liste(kontakt *poczatek, int rekordy);
int pobierz_liste_pom(FILE *fp,kontakt ***poczatek , kontakt ***koniec );

/////////////////////////////////////////////////////////

int main()
{
	int rekordy; //zliczanie wpisow
	rekordy = 0;
	
	//kontakty beda przechowywane w liscie dwukierunkowej
	kontakt *poczatek = NULL;
	kontakt *koniec = NULL;
	
	pobierz_liste(&poczatek , &koniec , &rekordy);
	wyswietl_liste(poczatek,rekordy);
	
	return 0;
}

////////////////////////////////////////////////////

void pobierz_liste(kontakt **poczatek , kontakt **koniec , int *rekordy)
{
	FILE *fp;
	if((fp = fopen("baza_danych.txt" , "rb")) == 0)
	exit(2);
		
			
	short pobierz = 1;
	
	while(pobierz)
	{
		pobierz = pobierz_liste_pom(fp, &poczatek , &koniec );
		(*rekordy)++;
	}
	
	if(fclose(fp) != 0)
	exit(3);
}

//////////////////////////////////////////////////////////

int pobierz_liste_pom(FILE *fp,kontakt ***poczatek , kontakt ***koniec)
{
		kontakt * nowy;
		nowy = (kontakt *)malloc(sizeof(kontakt));
		char pomoc;
		const char *c = &pomoc;
		
		{
			nowy->prev=(**koniec);
			if((**koniec) != NULL)(**koniec)->next = nowy;
			nowy->next = NULL;
			**koniec = nowy;
			if((**poczatek) == NULL) **poczatek = nowy;
		}
		
		while((pomoc = fgetc(fp)) != ',')
		{
			strcat(nowy->nazwisko,c);
		}
		
		strcat(nowy->nazwisko,c);
		
		printf("NAZWISKO: %s" , nowy->nazwisko);
		while((pomoc = fgetc(fp)) != ',')
		{
			strcat(nowy->imie,c);
		}
		pomoc = '\0';
		strcat(nowy->imie,c);
		while((pomoc = fgetc(fp)) != ',')
		{
			strcat(nowy->miasto,c);
		}
		pomoc = '\0';
		strcat(nowy->miasto,c);
		while((pomoc = fgetc(fp)) != ',')
		{
			strcat(nowy->ulica,c);
			printf("%c" , pomoc);
		}
		pomoc = '\0';
		strcat(nowy->ulica,c);
		fscanf(fp, "%d" , &(nowy->numer));
	
		fgetc(fp);
		nowy->dodatek = fgetc(fp);
		fgetc(fp);
		fscanf(fp,"%d" , &(nowy->mieszkania));
		fgetc(fp);
		while((pomoc = fgetc(fp)) != ',')
		{
			strcat(nowy->kod_pocztowy,&pomoc);
		}
		pomoc = '\0';
		strcat(nowy->kod_pocztowy,c);
		fgetc(fp);
		fscanf(fp,"%ld" , &(nowy->telefon));
		fgetc(fp);
		
		if((pomoc = fgetc(fp)) == EOF)
		{
			return 0;
		}
		
		else
		{
			ungetc(pomoc,fp);
			return 1;
		}
		
}

void wyswietl_liste(kontakt *poczatek, int rekordy)
{
	kontakt *wsk;
	wsk = poczatek;

	if(rekordy == 0)
	{
		printf("\n\t\tBaza danych jest obecnie pusta!\n\n");
		return;
	}	
	
	while(wsk)
    {
        printf("\n*********************************\n");
        printf("Nazwisko:" " %23s\n" , wsk->nazwisko);
        printf("Imie:" " %27s\n" , wsk->imie);
        printf("Miasto:" " %25s\n" , wsk->miasto);
        printf("Ulica:" " %26s\n" , wsk->ulica);
        printf("Numer:" " %23d" , wsk->numer);

    	if(wsk->dodatek != '0')
    		printf("%c" , wsk->dodatek);
        if(wsk->mieszkania != 0)
            printf("\\%d", wsk->mieszkania);

 		printf("\nKod pocztowy: " " %18s\n" , wsk->kod_pocztowy);
 	    printf("Telefon: " " %23d\n" , wsk->telefon);

   		wsk = wsk->next;
   		//printf("ADRES %d" , wsk ); TU COS SIE NIE ZGADZA(?)
    }

}

Przygotawałem dwie bazy danych, prostą z jednym wpisem i docelową, wystarczy skopiować do notatnika i zapisać jako baza_danych.txt

Brzeczyszczykiewicz,Grzegorz,Rawa,Rydza,2,0,0,89-200,888555444$
Brzeczyszczykiewicz,Grzegorz,Rawa,Rydza,2,0,0,89-200,888555444$Lukaszewicz,Kamil,Warszawa,Biala,9,a,1,01-200,123678900$Grzewuszki,Piotr,Lodz,Armii Krajowej,80,0,2,89-277,388999035$Pawlak,Michal,Szczecin,Debowa,1,9,0,7,54-100,123567900$Grzedek,Przemyslaw,Krakow,Krzywa,7,b,1,23-891,773332896$Adamek,Piotr,Warszawa,Mila,2,0,0,23-740,899123745$Wojtecki,Hubert,Warszawa,Smocza,4,0,2,34-380,723478512$Kasprowicz,Ferdynand,Warszawa,Jerozolimska,1,a,1,01-277,288999234$Uznam,Pawel,Piotrkow,Trubadurow,2,0.8,29-710,239432285$Wolanski,Andrzej,Leszno,Lipowa,21,a,8,55-900,983234111$

EDIT:
Cóż, być może odpowiedzią na mój problem jest odpowiedzenie na pytanie co złego jest w takim kodzie (ten sam txt), choć (co zaakcentowałem na koniec w komentarzu) wsk->next winno być NULL, a nie jest, tym niemniej to nie działa:

#include <stdio.h>
#include <string.h>

int main()
{
    FILE *fp;
    fp = fopen("baza_danych.txt","r");

    char nazwa[100];
    char pomoc;
    const char *c = &pomoc;
    while((pomoc = fgetc(fp)) != 'r')
    strcat(nazwa,c);

    pomoc = '\0';
    strcat(nazwa,pomoc);
    fclose(fp);
}
 
0
fscanf(fp," %[^,]99s %[^,]99s %[^,]99s %[^,]99s %d%c %d  %[^,]6s %lld",nowy->nazwisko,nowy->imie,nowy->miasto,nowy->ulica,nowy->numer,nowy->dodatek,nowy->mieszkania,nowy->kod_pocztowy,nowy->telefon);
0

Niestety, ale jakkolwiek bym tego nie zaimplementowal, czy z przecinkami czy bez, to program dziala niepoprawnie.

0

Miałeś niepoprawne wczytywanie, popraw i podaj kod o ile nie działa.

0
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>

/////////////////////////////////////////////////////////

typedef struct dane
{
	char nazwisko[100];
	char imie[100];

	char miasto[100];
	char ulica[100];
	int numer;
	char dodatek;
	int mieszkania;

	char kod_pocztowy[7];
	long telefon;
	
	struct dane *next, *prev;
	
	struct znajomosc *pierwsza_znajomosc;
} kontakt;

/////////////////////////////////////////////////////////

void pobierz_liste(kontakt **poczatek , kontakt **koniec , int *rekordy);
void wyswietl_liste(kontakt *poczatek, int rekordy);
int pobierz_liste_pom(FILE *fp,kontakt ***poczatek , kontakt ***koniec );

/////////////////////////////////////////////////////////

int main()
{
	int rekordy; //zliczanie wpisow
	rekordy = 0;
	
	//kontakty beda przechowywane w liscie dwukierunkowej
	kontakt *poczatek = NULL;
	kontakt *koniec = NULL;

	
	pobierz_liste(&poczatek , &koniec , &rekordy);
	wyswietl_liste(poczatek,rekordy);
	
	return 0;
}

////////////////////////////////////////////////////

void pobierz_liste(kontakt **poczatek , kontakt **koniec , int *rekordy)
{
	FILE *fp;
	if((fp = fopen("baza_danych2.txt" , "r")) == 0)
	exit(2);
		
	short pobierz = 1;
	
	while(pobierz)
	{
		pobierz = pobierz_liste_pom(fp, &poczatek , &koniec );
		(*rekordy)++;
	}
	printf("REKORDY %d" , *rekordy);
	
	if(fclose(fp) != 0)
	exit(3);
}

//////////////////////////////////////////////////////////

int pobierz_liste_pom(FILE *fp,kontakt ***poczatek , kontakt ***koniec)
{
		kontakt * nowy;
		nowy = (kontakt *)malloc(sizeof(kontakt));
		char pomoc;
		
		{
			nowy->prev=(**koniec);
			if((**koniec) != NULL)(**koniec)->next = nowy;
			nowy->next = NULL;
			**koniec = nowy;
			if((**poczatek) == NULL) **poczatek = nowy;
		}
		
                //no i tutaj starałem się wkleić to co mi przekazałeś, ale niestety z marnym skutkiem. Wszystkie dane po kolei są wpisywane do pola "nazwisko"  kolejno tworzących się                      
                //wskaźników na strukturę. Z tego co rozumiem, przecinki nie zostaną pobrane, więc muszę się ich pozbyć. Pytanie tylko jak...
		fscanf(fp," %[^,]99s %*c %[^,]99s %*c %[^,]99s %*c %[^,]99s %*c %d %*c%c %*c %d %*c %[^,]6s %*c %ld %*c" , nowy->nazwisko,nowy->imie,nowy->miasto,nowy->ulica,
				&(nowy->numer),&(nowy->dodatek),&(nowy->mieszkania),nowy->kod_pocztowy,&(nowy->telefon));
				
		
		if((pomoc = fgetc(fp)) == EOF)
		{
			return 0;
		}
		
		else
		{
			printf("JESTEM TU\n");
			ungetc(pomoc,fp);
			return 1;
		}
		
}

void wyswietl_liste(kontakt *poczatek, int rekordy)
{
	kontakt *wsk;
	wsk = poczatek;

	if(rekordy == 0)
	{
		printf("\n\t\tBaza danych jest obecnie pusta!\n\n");
		return;
	}	
	
	while(wsk)
    {
        printf("\n*********************************\n");
        printf("Nazwisko:" " %23s\n" , wsk->nazwisko);
        printf("Imie:" " %27s\n" , wsk->imie);
        printf("Miasto:" " %25s\n" , wsk->miasto);
        printf("Ulica:" " %26s\n" , wsk->ulica);
        printf("Numer:" " %23d" , wsk->numer);

    	if(wsk->dodatek != '0')
    		printf("%c" , wsk->dodatek);
        if(wsk->mieszkania != 0)
            printf("\\%d", wsk->mieszkania);

 		printf("\nKod pocztowy: " " %18s\n" , wsk->kod_pocztowy);
 	    printf("Telefon: " " %23d\n" , wsk->telefon);

   		wsk = wsk->next;
	}
}
0

Masz pochrzanione w pobierz_liste_pom, przerób na: int pobierz_liste_pom(FILE *fp,kontakt **poczatek , kontakt **koniec)
Wywołanie w pobierz_liste: pobierz = pobierz_liste_pom(fp, poczatek , koniec );

0

Zrobiłem tak jak mówiłeś, ale efekt dokładnie ten sam. Kompletnie nie wiem czemu to nie chce ruszyć.

0

No to kod lub do wróżbitów.

0
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
 
/////////////////////////////////////////////////////////
 
typedef struct dane
{
    char nazwisko[100];
    char imie[100];
 
    char miasto[100];
    char ulica[100];
    int numer;
    char dodatek;
    int mieszkania;
 
    char kod_pocztowy[7];
    long telefon;
 
    struct dane *next, *prev;
 
    struct znajomosc *pierwsza_znajomosc;
} kontakt;
 
/////////////////////////////////////////////////////////
 
void pobierz_liste(kontakt **poczatek , kontakt **koniec , int *rekordy);
void wyswietl_liste(kontakt *poczatek, int rekordy);
int pobierz_liste_pom(FILE *fp,kontakt **poczatek , kontakt **koniec );
 
/////////////////////////////////////////////////////////
 
int main()
{
    int rekordy; //zliczanie wpisow
    rekordy = 0;
 
    //kontakty beda przechowywane w liscie dwukierunkowej
    kontakt *poczatek = NULL;
    kontakt *koniec = NULL;
 
 
    pobierz_liste(&poczatek , &koniec , &rekordy);
    wyswietl_liste(poczatek,rekordy);
 
    return 0;
}
 
////////////////////////////////////////////////////
 
void pobierz_liste(kontakt **poczatek , kontakt **koniec , int *rekordy)
{
    FILE *fp;
    if((fp = fopen("baza_danych2.txt" , "r")) == 0)
    exit(2);
 
    short pobierz = 1;
 
    while(pobierz)
    {
        pobierz = pobierz_liste_pom(fp, &poczatek , &koniec );
        (*rekordy)++;
    }
    printf("REKORDY %d" , *rekordy);
 
    if(fclose(fp) != 0)
    exit(3);
}
 
//////////////////////////////////////////////////////////
 
int pobierz_liste_pom(FILE *fp,kontakt **poczatek , kontakt **koniec)
{
        kontakt * nowy;
        nowy = (kontakt *)malloc(sizeof(kontakt));
        char pomoc;
 
        {
            nowy->prev=(*koniec);
            if((*koniec) != NULL)(*koniec)->next = nowy;
            nowy->next = NULL;
            *koniec = nowy;
            if((*poczatek) == NULL) *poczatek = nowy;
        }
 
                //no i tutaj starałem się wkleić to co mi przekazałeś, ale niestety z marnym skutkiem. Wszystkie dane po kolei są wpisywane do pola "nazwisko"  kolejno tworzących się                      
                //wskaźników na strukturę. Z tego co rozumiem, przecinki nie zostaną pobrane, więc muszę się ich pozbyć. Pytanie tylko jak...
        fscanf(fp," %[^,]99s %*c %[^,]99s %*c %[^,]99s %*c %[^,]99s %*c %d %*c%c %*c %d %*c %[^,]6s %*c %ld %*c" , nowy->nazwisko,nowy->imie,nowy->miasto,nowy- >ulica,&(nowy->numer),&(nowy->dodatek),&(nowy->mieszkania),nowy->kod_pocztowy,&(nowy->telefon));
               
                //wersja druga, ale ona tez nie dziala:
                // fscanf(fp," %[^,]99s %*c %[^,]99s %*c %[^,]99s %*c %[^,]99s %*c %d %*c%c %*c %d %*c %[^,]6s %*c %ld %*c" , nowy->nazwisko,nowy->imie,nowy->miasto,                
                //nowy->ulica,,&(nowy->numer),&(nowy->dodatek),&(nowy->mieszkania),nowy->kod_pocztowy,&(nowy->telefon));
 
        if((pomoc = fgetc(fp)) == EOF)
        {
            return 0;
        }
 
        else
        {
            printf("JESTEM TU\n");
            ungetc(pomoc,fp);
            return 1;
        }
 
}
 
void wyswietl_liste(kontakt *poczatek, int rekordy)
{
    kontakt *wsk;
    wsk = poczatek;
 
    if(rekordy == 0)
    {
        printf("\n\t\tBaza danych jest obecnie pusta!\n\n");
        return;
    }    
 
    while(wsk)
    {
        printf("\n*********************************\n");
        printf("Nazwisko:" " %23s\n" , wsk->nazwisko);
        printf("Imie:" " %27s\n" , wsk->imie);
        printf("Miasto:" " %25s\n" , wsk->miasto);
        printf("Ulica:" " %26s\n" , wsk->ulica);
        printf("Numer:" " %23d" , wsk->numer);
 
        if(wsk->dodatek != '0')
            printf("%c" , wsk->dodatek);
        if(wsk->mieszkania != 0)
            printf("\\%d", wsk->mieszkania);
 
         printf("\nKod pocztowy: " " %18s\n" , wsk->kod_pocztowy);
         printf("Telefon: " " %23d\n" , wsk->telefon);
 
           wsk = wsk->next;
    }
} 
0

Może nie chce ruszyć poprzez ten wiersz: exit(2);

0

Zerknij tu:

void pobierz_liste(kontakt **poczatek , kontakt **koniec , int *rekordy)
{
    FILE *fp;
    if((fp = fopen("baza_danych2.txt" , "r")) == 0)
    exit(2);
0

Niet, problem leżał zupełnie, gdzie indziej. Oto działająca funkcja:

void pobierz_liste(kontakt **poczatek , kontakt **koniec , int *rekordy)
{
	FILE *fp;
	if((fp = fopen("baza_danych1.txt" , "r")) == 0)
	exit(2);
		
	short pobierz = 1;
	
	while(pobierz)
	{
		pobierz = pobierz_liste_pom(fp, poczatek , koniec );
		(*rekordy)++;
	}
	
	if(fclose(fp) != 0)
	exit(3);
}
int pobierz_liste_pom(FILE *fp,kontakt **poczatek , kontakt **koniec)
{
		kontakt * nowy;
		nowy = (kontakt *)malloc(sizeof(kontakt));
		char string[100];
		char pomoc;
		
		{
			nowy->prev=(*koniec);
			if((*koniec) != NULL)(*koniec)->next = nowy;
			nowy->next = NULL;
			*koniec = nowy;
			if((*poczatek) == NULL) *poczatek = nowy;
		}
		
		//postanowilem trzymac wszelkie stringi jako wielkie litery
		//pozwala to uniknac masy bledow
		//tutaj nastepuje wczytanie nazwisk z bazy
		
		//dzieki takiemu systemowy pobierania danych jak ponizej
		//nie mam problemu z pobieraniem wieloczlonowych stringow(np Aleja Jana Pawla II)
		//fgets pobiera znak nowej linii, wiec musze go recznie usunac
		fgets(string,100,fp);
		string[strlen(string) - 1] = '\0';
		to_upper(string);
		strcpy(nowy->nazwisko,string);
		
		fgets(string,100,fp);
		string[strlen(string) - 1] = '\0';
		to_upper(string);
		strcpy(nowy->imie,string);
		
		fgets(string,100,fp);
		string[strlen(string) - 1] = '\0';
		to_upper(string);
		strcpy(nowy->miasto,string);
		
		fgets(string,100,fp);
		string[strlen(string) - 1] = '\0';
		to_upper(string);
		strcpy(nowy->ulica,string);
		
		fgets(nowy->kod_pocztowy,7,fp);
		nowy->kod_pocztowy[strlen(nowy->kod_pocztowy)] = '\0';
		fscanf(fp,"%d" ,&(nowy->numer) );
		fscanf(fp, "%s" ,(nowy->dodatek) );
		fscanf(fp , "%d" ,&(nowy->mieszkania) );
		fscanf(fp , "%ld" ,&(nowy->telefon) );         
				 
		fgetc(fp);
		if((pomoc = fgetc(fp)) == EOF)
		{
			return 0;
		}
		
		else
		{
			ungetc(pomoc,fp); //jesli to jeszcze nie koniec, pobrany znak zostaje zwrocony
			return 1;
		}		
}

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