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", ®Nr);
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
