Exercise 2

Fra Wikipedia, den frie encyklopedi.

Innholdsfortegnelse

Videregående C-programering

Denne øvingen er forsåvidt lik den forrige, men her skal dere benytte dynamisk minnehåndtering ved lagring av feltene til bildene, samt ved lagring av biler i databasen. Bruk av dynamisk minnehåndtering gir to fordeler:

  • begrensningen på feltstørrelsene forsvinner (feltene kan ha vilkårlig lengde), og
  • en bruker ikke mer minne enn nødvendig (korte strenger tar mindre plass enn lange).

I tillegg skal det heller ikke være noen begrensning på størrelsen til bildatabasen.

Hint

Dere vil få bruk for malloc og free for å allokere og slette elementer.

bil2.h

#ifndef BIL2_H
#define BIL2_H

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

typedef struct {
		char* merke;
		char* modell;
		int   prod_aar;
		char* farge;
		int   reg_nr;
} bil;

enum muligeValg{
		NY_BIL,
		FINN_BIL,
		SLETT_ALT,
		EXIT
};

void nyBil(void);
void finnBil(void);
void tegnMeny();
void velgFunksjon(int);
void slettAlt(void);
void init_bil_db(void) ;
void free_bil_db(void);

#endif

bil2.c

#include "bil2.h"
#define MAX_ANTALL 15

bil* bilDB;
int  DB_SIZE;
int lengde = 0; // holds the number of rows in table bliDB

/* copies content of a zero terminated string */
char* copy_string(char* src) {
	// determine string length
	int length = 0;
	while (src[length] != 0)
		length++;
	length++; // to account for zero-termination

	// allocate destination string
	char* dest = (char*) malloc( sizeof(char)*length );

	// copy content
	int i = 0;
	for (i = 0; i < length; i++)
		dest[i] = src[i];

	return dest;
}

/* copy a string using string library.  */
char* copy_string_II(char* src) {
	// allocate destination string
	char* dest = (char*) malloc( sizeof(char)*strlen(src) );
	return strcpy(dest, src);
}

/* increase database size when it is full */
void increaseDB () {
	bil* tempDB;
	int i;

	DB_SIZE *= 2; // allocate new array which is twice as large
	tempDB = (bil*)malloc(sizeof(bil)*DB_SIZE);

	for (i = 0; i < lengde; i++)
		tempDB[i] = bilDB[i]; //move entries to new array

	free(bilDB);
	bilDB = tempDB;
}

/* search in table for a numeric value and present when found */
void finnBil() {
	int regNr;

	printf("Skriv inn registreringsnummeret til bilen du vil finne:\n");;
	printf("Maksimalt 8 siffer\n");
	scanf("%d", &regNr);

	int i;
	int funnet=0;
	for(i=0; i < lengde; i++ ){
		if(bilDB[i].reg_nr==regNr){
			printf("Merke: %s\n", bilDB[i].merke);
			printf("Type: %s\n", bilDB[i].modell);
			printf("Produksjonsaar: %i\n", bilDB[i].prod_aar);
			printf("Farge: %s\n", bilDB[i].farge);
			printf("Registereringsnummer: %i\n", bilDB[i].reg_nr);
			funnet=1;
			break;
		}
	}
	if (!funnet)
		printf("Bedre lykke neste gang?\n");
}

/* insert a new row in table */
void nyBil() {
	if (lengde >= DB_SIZE-1) {
		printf("Øker databasestørrelsen...\n");
		increaseDB();
	}

	char temp[1000];

	printf("Skriv inn bilmerke, maksimum 15 bokstaver:\n");
	scanf("%s", temp);
	bilDB[lengde].merke = copy_string(temp);

	printf("Skriv inn modell, maksimum 15 bokstaver:\n");
	scanf("%s", temp);
	bilDB[lengde].modell = copy_string(temp);

	printf("Skriv inn året bilen er produsert, fire siffer:\n");
	scanf("%d", &(bilDB[lengde].prod_aar));

	printf("Bilens farge, maksimum 15 bokstaver:\n");
	scanf("%s", temp);
	bilDB[lengde].farge = copy_string(temp);

	printf("Registreringsnummer, maksimum 8 siffer:\n");
	scanf("%i", &(bilDB[lengde].reg_nr));

	lengde++;
}

/* print the meny */
void tegnMeny() {
	int valg;

	printf("*****************************\n");
	printf(" Valgets kvaler...\n\n");
	printf(" [0] Legg til bil. \n");
	printf(" [1] Finn bil.\n");
	printf(" [2] Slett alle biler i database!\n");
	printf(" [3] Slutt programmet\n\n");
	printf("*****************************\n");

	scanf("%i",&valg);
	velgFunksjon(valg);
}

/* exit program with success. uses stdlib definition EXIT_SUCCESS */
void stikkAv() {
	printf("Talast!\n");
	exit(EXIT_SUCCESS);
}

/* choose action. Look at the enum declaration muligeValg in bil2.h */
void velgFunksjon(int valg) {
	switch(valg){
		case NY_BIL:
			nyBil();
			break;
		case FINN_BIL:
			finnBil();
			break;
		case SLETT_ALT:
			slettAlt();
			break;
		case EXIT:
			stikkAv();
			break;
	 	default:
	 	    printf("Ikke et gyldig valg. Prøv igjen!\n");
	}
	tegnMeny();
}

/* remove access to data in table. Free used space. */
void slettAlt() {
	int valg;

	printf("Sikker? Alt vil slettes ...\n");
	printf("[0] Ja!\n");
	printf("[1] Nei!\n");

	scanf("%i", &valg);

	if (valg==0) {
		free_bil_db();
		init_bil_db();
		printf("Database er slettet.\n");
	} else {
		printf("Ingen sletting utført.\n");
		tegnMeny();
	}
}

/* free the space used for each ponter in bil table
 * and free the space used by the table */
void free_bil_db(void) {
	int i;
	for (i=0;i<lengde; i++) {
		free(bilDB[i].merke);
		free(bilDB[i].modell);
		free(bilDB[i].farge);
	}
	free(bilDB);
}

/* allocate space for the table */
void init_bil_db(void) {
	DB_SIZE = 2;
	lengde = 0;
	bilDB = (bil*) malloc(sizeof(bil) * DB_SIZE);
}

int main() {
	init_bil_db();

	tegnMeny();
	exit(EXIT_SUCCESS);
}

Makefile

#
# my makefile for bil2

compute:	bil2.o
		gcc -o bil2 bil2.o -Wall

bil2.o:		bil2.c
		gcc -o bil2.o -c bil2.c -Wall
clean:
		rm *.o bil2
Personal tools