Baza adresowa

0

Witam, mam poważny problem z bazą adresową (danych).
Problem polega na tym, że zamiast w strukturze stringi przechowujące nazwisko imię, itp trzymać w normalnych tablicach np. char nazwisko[100], to wymyśliłem, że zrobię to tak: char * nazwisko. Co oznacza alokacje pamięci, ale pod pewnymi względami ma to swoje zalety.

Program ma wyświetlać bazę, dodawać nowy wpis, modyfikować istniejący i usuwać istniejący. Działa wszystko oprócz modyfikacji, a dokładniej w sytuacji gdy chce zmodyfikować wpis, który jest wcześniej zainicjowany (w sensie dodany już w procesie kompilacji, jako przykładowa baza), jeśli jest to wpis który dodałem już w trakcie wykonywania programu problemu nie ma.

Wiem na czym polega problem, że zamiast następujących linijek dla jakiegoś tam nazwiska (tak, długość trochę poraża):

char *imie = malloc (sizeof(char) * 100);
*imie = "Adam"
//modyfikacja
strcpy(imie, "Kamil")

mam:

char *imie = "Adam"
//modyfikacja
strcpy(imie, "Kamil")

Co jest niemożliwe. Jeśli do końca nie zrozumieliście, to proszę was o skompilowanie programu i:

  1. Spróbujcie zmodyfikować istniejący wpis, poprzez ponowne wpisanie tego samego nazwiska.
  2. Uruchomcie program ponownie, dodajcie nowy wpis, a potem zmodyfikujcie ten nowy wpis.

Pytam was jak w tym moim programie zainicjować jakoś bazę danych, bez przerabiania 600 linii kodu...

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

#define rozmiar 20

void clear_screen(void)
{
#ifdef linux
    system("clear");
#else
    system("cls");
#endif
}


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

int rekord = 0;

struct dane
{
	char * nazwisko;
	char * imie;
	
	char * miasto;
	char * ulica;
	int numer;
	char dodatek;
	int mieszkania;
	char * kod_pocztowy;
	
	int telefon;
};

struct dane ksiazka_adresowa[rozmiar] = {  { "Hajduk" , "Piotr" , "Warszawa" , "Glodna" , 3 , '\0', 0 , "90-200" , 232222222} ,
										{"Nowak" , "Krzysztof" , "Gniezno" , "Legionowo" , 3 , '\0' , 0 , "96-540" , 232312},
										{"Adamowicz" , "Krzysztof" , "Poznan" , "Legionowo" , 5 , '\0' , 0 , "11-260" , 8989},
										
 };
 
struct dane nowy;

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

void policz_rekordy();
void menu();

void sortuj(); //sortowanie bazy danych
int porownaj(int); //porowanie dwoch elemetow przy sortowaniu
void zamien(int); //zamiana elementow przy sortowaniu

int wyszukiwanie(); //wyszukiwanie binarne - przy dodawaniu nowego wpisu sprawdzone zostanie czy nie jest juz w bazie danych
								//jesli tak - dane zostana uaktualnione

void wyswietl_baze();
void dodaj_nowy(); //dodawanie nowego elementu, badz modyfikacja tego, ktory jest juz w bazie
int usun_rekord(); //usuwanie rekordu z bazy danych

void pobierz_string(char *);
void pobierz_imie(char *);
void pobierz_kod_pocztowy(char *);
/////////////////////////////////////////////////

int main()
{
	
	//inicjacja pamieci dla struktury sluzacej do dodania nowego wpisu
	
	{
		nowy.nazwisko = malloc( sizeof(char) * 100);
		nowy.imie = malloc( sizeof(char) * 100);
		nowy.miasto = malloc( sizeof(char) * 100);
		nowy.ulica = malloc(sizeof(char) * 100);
		nowy.kod_pocztowy = malloc( sizeof(char) * 100);
	}
	
	
	policz_rekordy();
	sortuj();
	
	int fun_num;
	int blad;
	
	menu();
	
	while(fun_num != 4)
	{

		printf("\n\tPodaj ktora funkcje chcesz uzyc (1-3): ");
		blad = scanf("%d" , &fun_num);

		if(blad == 0 || fun_num > 4 || fun_num < 1)
		{
			printf("\n\tNiepoprawne dane, wpisz ponownie: ");
			while(getchar() != '\n')
			continue;

			continue;
		}

		if(getchar() != '\n')
		{
			printf("\n\n\t\tUWAGA, TUTAJ MOGL ZAJS BLAD!\n\n");
			return 10;
		}

		switch(fun_num)
		{
			case 1: wyswietl_baze();	break;
			case 2: dodaj_nowy();	break;
			case 3: blad = usun_rekord(); if(blad != 0) return blad; break;
			case 4: 
				{
					free(nowy.nazwisko);
					free(nowy.imie);
					free(nowy.miasto);
					free(nowy.ulica);
					free(nowy.kod_pocztowy);
				}
				break;
		}
	}
	
	printf("\n\n\tDziekuje za poswiecony czas!\n");
	return 0;
}

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

void policz_rekordy()
{
	int i = 0;
	while( ksiazka_adresowa[i].nazwisko != '\0' )
		i++;
	
	rekord = i;	
}

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

void menu()
{
	printf("*****************************************************\n");
	printf("******Napisane przez: XXXXX XXXXXXXXX , XX.11.2014********\n");
	printf("*****************************************************\n\n\n");
	printf("\tWitam w najoryginalniejszej ksiazce adresowej\n\t   w historii. Oto dostepne funkcje:\n\n"
		   "\t****  1.Wyswietl zawartosc bazy   ****\n"
		   "\t****    2.Dodaj/modyfikuj wpis    ****\n"  
		   "\t****          3.Usun wpis         ****\n"
		   "\t****           4.KONIEC           ****\n\n" );
}

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

void wyswietl_baze()
{
	int i = 0;
	
	if(rekord == 0)
	printf("\n\t\tBaza danych jest obecnie pusta!\n\n");
	
	while(ksiazka_adresowa[i].nazwisko)
	{
		printf("\n*********************************");
		printf("\n\nNumer ID:" " %23d\n" , i);
		printf("Nazwisko:" " %23s\n" , ksiazka_adresowa[i].nazwisko);
		printf("Imie:" " %27s\n" , ksiazka_adresowa[i].imie);
		printf("Miasto:" " %25s\n" , ksiazka_adresowa[i].miasto);
		printf("Ulica:" " %26s\n" , ksiazka_adresowa[i].ulica);
		printf("Numer:" " %23d" , ksiazka_adresowa[i].numer);
			
		if(ksiazka_adresowa[i].dodatek != '\0')
			printf("%c", ksiazka_adresowa[i].dodatek);
		if(ksiazka_adresowa[i].mieszkania != 0)
			printf("\\%d", ksiazka_adresowa[i].mieszkania);
			
		printf("\n");
		printf("Telefon:" " %24d\n" , ksiazka_adresowa[i].telefon );
		
		i++;
	}
}

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

void sortuj()
{
	int j = rekord - 1;
	int p , i;
	
	while(j > 0)
	{
		p = 0;
		i = 0;
		
		while(i < j)
		{
			if(porownaj(i))
			{
				zamien(i);
				p = 1;
			}
			i++;
		}
		
		if(p==0)
		return;
		
		else
		j--;
	}
	return;
}

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

int porownaj(int i)
{
	if(ksiazka_adresowa[i].nazwisko == '\0') return 1; 
	if(ksiazka_adresowa[i+1].nazwisko == '\0') return 0;
	
	int porownanie1 = strcmp( ksiazka_adresowa[i].nazwisko, ksiazka_adresowa[i+1].nazwisko);

	int porownanie2;
	
	if( porownanie1 > 0)
		return 1;
	
	if( porownanie1 < 0)
		return 0;
		
	if( porownanie1 == 0)
	{
		porownanie2 = strcmp(ksiazka_adresowa[i].imie, ksiazka_adresowa[i+1].imie);
	
		if( porownanie2 > 0)
			return 1;
	
		else
			return 0;
	}	
}

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

void zamien(int i)
{
	struct dane tymczasowa = ksiazka_adresowa[i];
	ksiazka_adresowa[i] = ksiazka_adresowa[i+1];
	ksiazka_adresowa[i+1] = tymczasowa;	
}

int usun_rekord()
{
	if(rekord == 0)
	{
		printf("\n\n\t\tBaza danych jest obecnie pusta!\n\n\n");
		return 0;
	}
	
	char c;
	int blad = 0;
	int rekord_do_usuniecia;
	
		printf("\n\tUWAGA, usunietych rekordow nie da sie juz odzyskac!\n");
		printf("\tWpisz y, aby zatwierdzic,\n\tbadz dowolny inny znak by wrocic do menu\n");

		while((blad = scanf("%c" , &c)) != 1)
		{
			printf("Blad, sprobuj ponownie\n");
			while(getchar() != '\n');
			continue;
			
			continue;
		}
		
		if(c != 'y')
		return 0;

		printf("\tPodaj numer ID rekordu do usuniecia: ");
		
		while(1)
		{			
			blad = scanf("%d" , &rekord_do_usuniecia );
					
			if(blad == 0)
			{
				printf("\tBlad, sprobuj ponownie: \n");
			
				while(getchar() != '\n');
				continue;
					
				continue;
			}
			
			if(getchar() != '\n')
			{
				printf("\n\n\t\tUWAGA, TUTAJ MOGL ZAJS BLAD!\n\n");
				return 10; //bufor nie jest czysty po pobraniu znaku/liczby
			}
				
			if(rekord_do_usuniecia < 0 || rekord_do_usuniecia > rekord)
			{
				printf("\tNie ma takiego rekordu, sprobuj ponownie:\n");
				
				if(getchar() != '\n')
				{
					printf("\n\n\t\tUWAGA, TUTAJ MOGL ZAJS BLAD!\n\n");
					return 10; //bufor nie jest czysty po pobraniu znaku/liczby
				}
				continue;
			}	
			break;
		}
		
		
	ksiazka_adresowa[rekord_do_usuniecia].nazwisko= '\0';
	
	sortuj();
	rekord--;
	
	clear_screen();
	
	return 0;
}

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

void dodaj_nowy()
{
	int pozycja;
	int blad = 0;
	char * string = malloc(100);
	
	if(rekord >rozmiar-1)
	{
		printf("\n\tBaza danych jest zapelniona!\n");
		return;
	}
	
	printf("\n\tNazwisko: ");
		pobierz_string(string);
		strcpy( nowy.nazwisko, string);
	//
	
	printf("\n\tImie: ");	
		pobierz_imie(string);
		strcpy( nowy.imie, string);
	//
	
	printf("\n\tMiasto: ");
		pobierz_string(string);
		strcpy( nowy.miasto, string);
	//
	
	printf("\n\tUlica: ");
		pobierz_string(string);
		strcpy( nowy.ulica, string);
	//
	
	printf("\n\tNumer domu: ");
		scanf("%d" , &nowy.numer);
	//	
	
	printf("\n\tKod pocztowy: ");
		pobierz_kod_pocztowy(string);
		strcpy( nowy.kod_pocztowy ,string);
	//
	
	printf("\n\tNumer telefonu: ");
		scanf("%d" , &nowy.telefon);
	//
	
	pozycja = wyszukiwanie();
	printf("%d" , pozycja);
	
	if( pozycja > -1)
	{
		printf("aaa");
		strcpy(ksiazka_adresowa[pozycja].nazwisko , nowy.nazwisko);
		printf("TU JEST BLAD");
		strcpy(ksiazka_adresowa[pozycja].imie , nowy.imie);
		printf("aaa");
		strcpy(ksiazka_adresowa[pozycja].miasto , nowy.miasto);
		strcpy(ksiazka_adresowa[pozycja].ulica , nowy.ulica);
		printf("aaa");
		ksiazka_adresowa[pozycja].numer = nowy.numer;
		printf("aaa");
		strcpy(ksiazka_adresowa[pozycja].kod_pocztowy , nowy.kod_pocztowy);
		printf("aaa");
		ksiazka_adresowa[pozycja].telefon = nowy.telefon;
		printf("aaa");
	}
	
	else
	{
		
		ksiazka_adresowa[rekord].nazwisko = malloc(100);
		ksiazka_adresowa[rekord].imie = malloc(100);
		ksiazka_adresowa[rekord].miasto= malloc(100);
		ksiazka_adresowa[rekord].ulica = malloc(100);
		ksiazka_adresowa[rekord].kod_pocztowy = malloc(100);
		
		strcpy(ksiazka_adresowa[rekord].nazwisko , nowy.nazwisko);
		strcpy(ksiazka_adresowa[rekord].imie , nowy.imie);
		strcpy(ksiazka_adresowa[rekord].miasto , nowy.miasto);
		strcpy(ksiazka_adresowa[rekord].ulica , nowy.ulica);
		ksiazka_adresowa[rekord].numer = nowy.numer;
		strcpy(ksiazka_adresowa[rekord].kod_pocztowy , nowy.kod_pocztowy);
		ksiazka_adresowa[rekord].telefon = nowy.telefon;
	
		rekord++;
	}
	
	printf("\nAAA\n");
	sortuj();
}
	
///////////////////////////////////////

void pobierz_string( char * string_pierwotny)
{
	char * string = malloc(100);
	
	while(1)
	{
		scanf("%s" , string);
	
		if(getchar() != '\n')
		{
			printf("Blad! Sprobuj jeszcze raz:\n");
			
			while(getchar() != '\n')
			continue;
			
			continue;
		}
		
		if(string[0] < 'A' || string[0] > 'Z')
		{
			printf("Obowiazkowo na pierwszym miejscu musi stac duza litera\n Sprobuj jeszcze raz:\n");
			continue;
		}
		
		if(strlen(string) > 99)
		{
			printf("Ten string jest za dlugi! Sprobuj ponownie\n");
			continue;
		}
		
		break;	
	}
	
	strcpy(string_pierwotny , string);
	
	free(string);
		
}

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

void pobierz_imie(char * string_pierwotny) // jest to wariacja na temat fukcji pobierz string, ktora dopuszcza dluczlonowy string w formacie XXXXX XXXXX
{
	char * string = malloc(100);
	char * pomoc = malloc(100);
	
	while(1)
	{
		scanf("%s" , string);
		
		char c;
		if( (c = getchar()) == ' ') 
		{
			scanf("%s" , pomoc);
			strcat(string ," ");
			strcat(string ,pomoc);
		}
	
		if(getchar() != '\n')
		{
			printf("Blad! Sprobuj jeszcze raz:\n");
			
			while(getchar() != '\n')
			continue;
			
			continue;
		}
		
		if(string[0] < 'A' || string[0] > 'Z')
		{
			printf("Obowiazkowo na pierwszym miejscu musi stac duza litera\n Sprobuj jeszcze raz:\n");
			continue;
		}	
		
		if(strlen(string) > 99)
		{
			printf("Ten string jest za dlugi! Sprobuj ponownie\n");
			continue;
		}
		
		break;
	}
	
	strcpy(string_pierwotny , string);
	
	free(string);
	free(pomoc);
}
//////////////////////////////////////

void pobierz_kod_pocztowy(char * string_pierwotny)
{
		char * string = malloc(100);
		int i;
		int blad;

	while(1)
	{
		i = 0;
		blad = 0;
		
		scanf("%s" , string);
	
		if(getchar() != '\n')
		{
			printf("Blad! Sprobuj jeszcze raz:\n");
			
			while(getchar() != '\n')
			continue;
			
			continue;
		}
		
		while(i < 6)
		{
			if(i == 2)
			if(string[2] != '-')
			{
				printf("Zly format kodu pocztowego, wpisz ponownie:\n");
				blad = 1;
			}
			else
			i++;
			
			if(blad)
			break;
			
			if(!isdigit(string[i]))
			{
				printf("Zly format kodu pocztowego, wpisz ponownie:\n");
				blad = 1;

			}
			
			if(strlen(string) > 7)
			{
				printf("Zly format kodu pocztowego, wpisz ponownie:\n");
				blad = 1;
			}
			
				if(blad)
				break;
			i++;
		}
		
		if(blad)
		continue;
		
		else
		break;	
	}
	
	strcpy(string_pierwotny, string);
	free(string);
	
}

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

int wyszukiwanie()
{
	int poczatek , koniec , piwot , znaleziono;
	
	poczatek = 0;
	koniec = rekord - 1;
	
	while(poczatek <= koniec)
	{
		piwot = (poczatek+koniec)/2;
	
		if(strcmp(ksiazka_adresowa[piwot].nazwisko , nowy.nazwisko) == 0)
		{
			return piwot;
		}
		
		if(strcmp(ksiazka_adresowa[piwot].nazwisko , nowy.nazwisko) < 0)
		{
			poczatek = piwot + 1;
			continue;
		}
		
		if(strcmp(ksiazka_adresowa[piwot].nazwisko , nowy.nazwisko) > 0)
		{
			koniec = piwot - 1;
			continue;
		}
	}
	return -1;
}
0
 
char *imie = malloc(sizeof(char)*100);
char *imie = "Adam";

Jeżeli masz takie coś na myśli to nie radze nikomu tego włączać bo fajny wyciek pamięci powstaje (chociaż w dzisiejszych czasach to mało prawdopodobne, zwolni się).

Ja tu tylko ostrzegam, nie rozumiem za bardzo pytania sorry :P

0

Pytanie sprowadza się do tego, że nie można zmodyfikować wpisu, który został dodany w czasie kompilacji.
Modyfikacji dokonuje się poprzez dodanie wpisu o tym samym nazwisku.

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