Kontinuasjonseksamensoppgave i IMT1082 Objekt-orientert programmering

Like dokumenter
Kontinuasjonseksamensoppgave i IMT1082 Objekt-orientert programmering

Eksamensoppgave i IMT1082 Objekt-orientert programmering

Eksamensoppgave i IMT1082 Objekt-orientert programmering

Kontinuasjonseksamen

Eksamen. Objekt-orientert programmering

Kontinuasjonseksamensoppgave i IMT1031(F) Grunnleggende programmering

Eksamen. Grunnleggende programmering. EKSAMENSDATO: 6.desember 2016 TID: 16:00 20:00. (kalkulator er ikke tillatt)

Kontinuasjonseksamen

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Kontinuasjonseksamen

Kontinuasjonseksamen

Eksamen. Objekt-orientert programmering KLASSE(R): 02HIND* 02HDMU* 02HINE* 02HING* 01HINGA 02HSIV5 02HGEOMAA

Kontinuasjonseksamen

Kontinuasjonseksamen

E K S A M E N. Grunnleggende programmering 03HBIND*, 03HBINFA, 03HBINE*, 03HBMETEA, 03HBMEMAA, 03HBGEOA

Eksamen. Objekt-orientert programmering 04HBIND*, 04HBINFA, 04HBMETEA

Høgskolen i Gjøvik Institutt for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Kontinuasjonseksamen

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Kontinuasjonseksamen

Kontinuasjonseksamen

Kontinuasjonseksamen

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Kontinuasjonseksamen

Eksamen. Objekt-orientert programmering 03HBIND*, 03HBINFA, 03HBMETEA

Kontinuasjonseksamen

Kontinuasjonseksamen

KONTINUASJONSEKSAMEN

E K S A M E N. Grunnleggende datakunnskap og programmering 02HIND*, 02HINE*, 02HDMU*, 02HING*, 02HGEOMAA, 02HSIV5

Kontinuasjonseksamen

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Kontinuasjonseksamen

Kontinuasjonseksamen

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Kontinuasjonseksamen

KONTINUASJONSEKSAMEN

Høgskolen i Gjøvik. Eksamen. Objekt-orientert programmering 98HINDA / 98HINDB / 98HINEA 98HDMUA / 98HDMUB

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Høgskolen i Gjøvik Institutt for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Kontinuasjonseksamen

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Kontinuasjonseksamen

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Kontinuasjonseksamen

E K S A M E N 96HINDA / 96HINDE (1 AA / AE)

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Eksamen. Objekt-orientert programmering

Eksamen. Objekt-orientert programmering. EKSAMENSDATO: 25. mai HINDA / 99HINDB / 99HINEA 99HDMUA / 99HDMUB TID: Høgskolen i Gjøvik

KONTINUASJONSEKSAMEN

KONTINUASJONSEKSAMEN

GJØVIK INGENIØRHØGSKOLE

Eksamen 00HINDA / 00HINDB / 00HINEA 00HDMUA / 00HDMUB

KONTINUASJONSEKSAMEN

KONTINUASJONSEKSAMEN

E K S A M E N. Grunnleggende datakunnskap og programmering. EKSAMENSDATO: 5. desember HIND*, 01HINE*, 01HDMU*, 01HING* TID:

E K S A M E N. Grunnleggende datakunnskap og programmering 99HINDA / 99HINDB / 99HINEA 99HDMUA / 99HDMUB / 99HINGA

Kontinuasjonseksamen

E K S A M E N. - Kontroller at alle oppgavearkene er tilstede. - Les hele oppgaveteksten nøye, før du begynner å besvare noe som helst.

Kontinuasjonseksamen

E K S A M E N. Grunnleggende datakunnskap og programmering 98HINDA / 98HINDB / 98HINEA 98HDMUA / 98HDMUB / 98HINGA

Grunnleggende datakunnskap og programmering. EKSAMENSDATO: 16. desember 1997

K O N T I N U A S J O N S E K S A M E N

Kontinuasjonseksamen

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

E K S A M E N. Grunnleggende programmering 04HBIND*, 04HBINE*, 04HBINFA, 04HBMETEA, 04HBGEOA. ANTALL SIDER UTLEVERT: 8 (inkludert denne forside)

Høgskolen i Gjøvik. Avdeling for elektro- og allmennfag K O N T I N U A S J O N S E K S A M E N. EKSAMENSDATO: 8. august 1995 TID:

Grunnleggende datakunnskap, programmering og datastrukturer 97HINDA / 97HINDB / 97HDMUA

GJØVIK INGENIØRHØGSKOLE

E K S A M E N. Grunnleggende datakunnskap og programmering. EKSAMENSDATO: 7. desember HINDA / 00HINDB / 00HINEA 00HDMUA / 00HDMUB / 00HINGA

Eksamen 01HIND* / 01HINE* / 01HDMU*

KONTINUASJONSEKSAMEN

Høgskolen i Gjøvik E K S A M E N. FAGLÆRER: Frode Haug KLASSE: 1 AA / AE

Kontinuasjonseksamen

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

HØGSKOLEN I SØR-TRØNDELAG

UNIVERSITETET I OSLO

Programmering i C++ Løsningsforslag Eksamen høsten 2005

HØGSKOLEN I SØR-TRØNDELAG

HØGSKOLEN I SØR-TRØNDELAG

UNIVERSITETET I OSLO

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

HØYSKOLEN I OSLO, AVDELING FOR INGENIØRUTDANNING

Kapittel 1 En oversikt over C-språket

Høgskolen i Gjøvik. Avdeling for elektro- og allmennfag K O N T I N U A S J O N S E K S A M E N. EKSAMENSDATO: 11. august 1995 TID:

1. Grunnleggende C Introduksjon til kurset og til C++ Innhold

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Høgskolen i Gjøvik. Avdeling for elektro- og allmennfag E K S A M E N. EKSAMENSDATO: 12. desember 1995 TID:

i «IMT Objekt-orientert programmering» våren 2019

Prosjektoppgave. i «IMT Objekt-orientert programmering» våren 2016

HØGSKOLEN I SØR-TRØNDELAG

UNIVERSITETET I OSLO

EKSAMENSFORSIDE Skriftlig eksamen med tilsyn

Transkript:

Institutt for datateknologi og informatikk Kontinuasjonseksamensoppgave i IMT1082 Objekt-orientert programmering Faglig kontakt under eksamen: Frode Haug Tlf: 950 55 636 Eksamensdato: 14.august 2017 Eksamenstid (fra-til): Hjelpemiddelkode/Tillatte hjelpemidler: 09:00-13:00 (4 timer) F - Alle trykte og skrevne. (kalkulator er ikke tillatt) Annen informasjon: Målform/språk: Antall sider (inkl. forside): 8 Norsk Informasjon om trykking av eksamensoppgaven Originalen er: 1-sidig X 2-sidig sort/hvit X farger Skal ha flervalgskjema Kontrollert av: Dato Sign

NB1: Oppgave 1a, 1b, 1c og 2 er totalt uavhengige og kan derfor løses separat. NB2: I hele oppgavesettet forutsetter vi at bruken av strcpy virker problemfritt - uten melding fra kompilatoren. Oppgave 1 (30%) a) Det nedenfor stående programmet var det ønskelig at gav følgende utskrift: Marit + Harald = Sant, den: 19/8-2017 Daniel + Solfrid = Sant, den: 9/9-2017 1.pars ektefelle kommer IKKE først i alfabetet. 2.pars ektefelle kommer først i alfabetet. Men, i koden er det fem feil av typen syntaktiske (som kompilatoren reagerer på) og/eller semantiske (logiske, som gjør at programmet ikke fungerer som ønsket). Hvilke? NB: Tallene helt til venstre på hver linje er ikke en del av koden, men kun ment som linjenummer, slik at du enklere kan henvise til hvor feilene er å finne. 1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 class Bryllup { 5 private: 6 char navn1[20], navn2[20]; 7 int dato; 8 public: 9 Bryllup(char* t1, * t2, int d) 10 { strcpy(navn1, t1); strcpy(navn1, t2); dato = d; 11 void skrivdato() { cout << dato / 10000 << '/' << (dato % 10000) / 100 12 << "-20" << dato / 100; 13 void display() { cout << navn1 << " + " << navn2 << " = Sant, den: "; 14 skrivdato(); cout << '\n'; 15 bool forstemindre() { return ( strcmp(navn1, navn2) < 0); 16 ; 17 int main() { 18 Bryllup *bryllup1 = new Bryllup("Marit", "Harald", 190817); 19 *bryllup2 = new Bryllup("Daniel", "Solfrid", 90917); 20 bryllup1->display(); bryllup2->display(); 21 cout << "1.pars ektefelle kommer " 22 << ((!bryllup1->forstemindre())? "IKKE " : "") 23 << "først i alfabetet.\n"; 24 cout << "2.pars ektefelle kommer " 25 << ((!bryllup2->forstemindre())? "IKKE " : "") 26 << "først i alfabetet.\n"; 27 return 0; 28 2

b) Hva blir utskriften fra følgende program (litt hjelp: det blir 5 linjer): #include <iostream> using namespace std; char txt[] = "MINNEVERDIG-CAMPINGBRYLLUP-PAA-KNATTEN"; void funk(char* t) { while (*t!= 'N') cout << *t++; char funk(char* t1, char* t2) { while (*t1!= *t2) { t1++; t2++; ; return *t1; void funk(char* t, int n) { t-= n; while (*t <= 'N') { cout << *t; t += 2; void funk(char* t1, char* t2, int n) { while (t1 > t2) { cout << *t1 << *t2 << ' '; t1-=n; t2+=n; char* funk(char* t, int n, char c) { while (*t!= c) { t += (*t >= 'H')? n : 2; return --t; int main() { funk(txt + 13); cout << '\n'; cout << funk(txt + 4, txt + 20) << '\n'; funk(txt + 12, 4); cout << '\n'; funk(txt + 37, txt + 5, 6); cout << '\n'; cout << funk(txt, 3, '-') << '\n'; return 0; c) Hva blir utskriften fra følgende program (litt hjelp: det blir 5 linjer): #include <iostream> using namespace std; class A { protected: int a1, a2; public: A(int a) { a1 = 3 * a / 5; a2 = a / 7; virtual void display() { cout << a1 << ' ' << a2 << ' '; bool operator < (int a) { return (a1+a2 < a); int operator * (int a) { return (a2 * a); ; class B : public A { private: int a1, a3; public: B(int a, int b) : A(b) { a1 = a; a3 = a1*b; void display() { A::display(); cout << a1 << ' ' << a3; int operator - (int a) { return (a1 + a2 + a3 + A::a1 - a); ; int main() { A* aob = new A(12); aob->display(); cout << '\n'; B* bob = new B(15, 6); bob->display(); cout << '\n'; A* aob2 = new A(30); aob2->display(); cout << ((*aob2) < 20) << ' ' << ((*aob2) * 6) << '\n'; A* aob3 = new B(11, 8); aob3->display(); cout << '\n'; B* bob2 = new B(10, 6); cout << ((*bob2-3)) << '\n'; return 0; 3

Oppgave 2 (70%) Les hele teksten for denne oppgaven nøye, før du begynner å besvare noe som helst. Studér vedlegget, som inneholder mange viktige opplysninger som du trenger/skal bruke. Legg spesielt merke til consten, klassene med datamedlemmer og funksjoner, globale variable, main og de tre les-funksjonene. Bruk disse siste svært aktivt. Det skal lages et program som holder orden på ulike hovedkategorier av gjøremål ved et arrangement (f.eks. bryllup), oppgavene innenfor hver kategori og status for hver av disse oppgavene igjen. Datastrukturen Datastrukturen består (se vedlegget) av listen arrangement med Kategori-objekter inni. Hver Kategori igjen har hver sin liste med Oppgave-objekter. sistekategori holder automatisk orden på hvilket nummer en ny kategori skal få. Det tilsvarende for en ny oppgave gjør datamedlemmet sisteoppgavenr inni hver Kategori. Globale variable, klassene, deres arv, alle data-medlemmer og alle prototyper for medlemsfunksjoner er så godt som komplett og fullstendig deklarert/definert i vedlegget. Din oppgave blir å skrive innmaten til funksjoner inni og utenfor klassene. Oppgaven a) Skriv innmaten til funksjonen Kategori::display() Funksjonen skriver ut på skjermen alle objektets data, unntatt listen med oppgaver og sisteoppgavenr. For listen skrives bare antall oppgaver i den. (NB: Legg merke til hvordan funksjonen blir brukt ifm. kommandoen A i main.) b) Skriv innmaten til funksjonene void skrivaltomengittkategori(), Kategori::display2() og Oppgave::display() Den første funksjonen spør brukeren først om et aktuelt kategorinummer. Finnes det ingen kategori med dette nummeret, kommer det bare en egen melding. I motsatt fall tas den aktuelle kategorien ut av lista, og dets display2-funksjon kalles. Denne funksjonen igjen viser det samme som i oppgave 2a, bare at den i tillegg viser hele oppgaver. Dette realiseres bl.a. vha. den siste funksjonen, som skriver alle oppgavens data, inkludert at hver enum-verdi skrives ut som en tilsvarende tekst. c) Skriv innmaten til funksjonene void nykategori() og Kategori::Kategori(int nr) Den første funksjonen gir den nye kategorien automatisk et nummer som er en høyere enn den forrige. Dette nummeret blir skrevet ut på skjermen. Deretter opprettes en ny kategori, og den legges inn i aktuell liste. Constructoren leser inn data til de to tekstene, og initierer/nullstiller de andre datamedlemmene. 4

d) Skriv innmaten til funksjonene void endreoppgavestatus(), Kategori::endreOppgaveStatus() og Oppgave::endreStatus() Den første funksjonen gjør det samme om den første i 2b, bare at i stedet for display2 kalles den andre funksjonen. Denne funksjonen igjen skriver først ut alt om kategorien på skjermen. Deretter ber den om et aktuelt oppgavenummer. Finnes ikke denne kommer det bare en melding. I motsatt fall tas oppgaven ut av listen, og den tredje funksjonen kalles. Denne tilbyr brukeren å endre status til en av de fem verdiene. La alternativene være (den første bokstaven i de ulike verdiene): I, P, H, N, og F. Du trenger ikke å ha noen kontroll på at det endres til en ny eller høyere verdi. Brukeren kan også velge noe annet enn de fem bokstavene. Da kommer det bare en feilmelding og ingen endring foretas. e) Det å lage og legge inn en ny oppgave, er såpass likt med det samme for en ny kategori (jfr. oppgave 2c). Derfor er dette utelatt i denne eksamensoppgaven. Datamedlemmet sisteoppgavenr ville derfor ha blitt telt opp lokalt inni hver kategori. La nå i stedet denne variabelen være global (som sistekategori). Dermed vil alle oppgaver i hele programmet få unike numre, uavhengig av hvilken oppgaver-liste de ligges inn i. Omskriv innmaten til den første funksjonen i 2d og (lag) alle andre påkrevde funksjoner/kode. f) Skriv innmaten til de tre skrivtilfil()-funksjonene Hele datastrukturen skal skrives til filen BRYLLUP1.DTA. Formatet bestemmer du helt selv, men den skal oppgis som en del av besvarelsen. g) Skriv innmaten til funksjonen void lesfrafil() og constructoren med to parametre i begge klassene Funksjonene skal til sammen sørge for at hele datastrukturen blir lest inn igjen fra filen BRYLLUP1.DTA (etter det formatet du selv bestemte i forrige oppgave). Annet (klargjørende): Du skal bruke ListTool2A ifm. løsningen av denne oppgaven. Du skal ikke bruke string-klassen (læreboka side 302-310), kode fra STL, templates eller andre større hjelpebiblioteker. Men, de vanligste includer brukt i hele 1.klasse er tilgjengelig. Legg merke til at: både kategorier og oppgaver er identifisert via kun numre (ikke tekst). det ikke skal lages funksjoner/kode for å fjerne/slette hverken en kategori eller en oppgave. sistekategori og sisteoppgavenr (når den er et datamedlem) ikke sier noe om antallet i listene de er tilknyttet. For hadde vi laget kode for å fjerne kategorier/oppgaver, så hadde det blitt «hull» i nummereringen. De representerer bare neste nummer som skal tas i bruk i en fortløpende automatisk høyere nummerering. status er kun en av de fem verdiene. Vi forutsetter at disse fem er beskrivende/gode nok. Gjør dine egne forutsetninger og presiseringer av oppgaven, dersom du skulle finne dette nødvendig. Gjør i så fall klart rede for disse i starten av din besvarelse av oppgaven. Lykke til og hurra for brudeparet! FrodeH 5

Vedlegg: Halvferdig programkode #include <iostream> #include <fstream> #include <cstring> #include <cctype> #include "ListTool2A.h" using namespace std; // INCLUDE: // cin, cout // ifstream // strcpy, strlen, strstr // toupper // CONST og ENUM: const int STRLEN = 80; // Max. lengde for en tekststreng. // Status for en oppgave: enum Status { IntetGjort, Paabegynt, Halvferdig, NestenFerdig, Ferdig ; // KLASSER: class Kategori : public NumElement { private: // number = kategoriens unike nummer/id. char* navn, // Kategoriens navn/tittel. * ansvarlig; // Navn på ansvarlig for hele kategorien. int sisteoppgavenr; // Siste oppgavenummer i kategorien hittil. List* oppgaver; // Liste med kategoriens oppgaver. public: Kategori(int nr); // Oppgave 2C Kategori(int nr, ifstream & inn); // Oppgave 2G ~Kategori() { delete [] navn; delete [] ansvarlig; delete oppgaver; void display(); // Oppgave 2A void display2(); // Oppgave 2B // void nyoppgave(); // (Skal ikke lages) void endreoppgavestatus(); // Oppgave 2D void skrivtilfil(ofstream & ut); // Oppgave 2F ; class Oppgave : public NumElement { private: // number = oppgavens unike nummer/id. char* tittel; // Oppgavens tittel/navn. Status status; // Oppgavens status (så langt). public: // Oppgave(int nr); // (Skal ikke lages) Oppgave(int nr, ifstream & inn); // Oppgave 2G ~Oppgave() { delete [] tittel; // void display(); // Oppgave 2B void endrestatus(); // Oppgave 2D void skrivtilfil(ofstream & ut); // Oppgave 2F ; // DEKLARASJON AV FUNKSJONER: void skrivmeny(); // char les(); // Ferdiglaget int les(const char* t, const int MIN, const int MAX); // void les(const char* t, char* s, const int LEN); // void skrivaltomengittkategori(); // Oppgave 2B void nykategori(); // Oppgave 2C void endreoppgavestatus(); // Oppgave 2D og 2E void skrivtilfil(); // Oppgave 2F void lesfrafil(); // Oppgave 2G // GLOBALE VARIABLE: List* arrangement; // Liste med alle kategoriene. int sistekategori = 0; // Siste kategorinr i bruk hittil. 6

int main() { // HOVEDPROGRAM: char valg; // Brukerens valg/kommando. arrangement = new List(Sorted); // Initierer tom kategori-liste. lesfrafil(); skrivmeny(); cout << "\n\n\nkommando: "; valg = les(); while (valg!= 'Q') { switch (valg) { case 'A': arrangement->displaylist(); break; // Oppgave 2A case 'K': skrivaltomengittkategori(); break; // Oppgave 2B case 'N': nykategori(); break; // Oppgave 2C case 'E': endreoppgavestatus(); break; // Oppgave 2D default: skrivmeny(); break; cout << "\n\n\nkommando: "; valg = les(); skrivtilfil(); cout << "\n\n"; return 0; // ************************************************************************* // ****************** DEFINISJON AV MEDLEMS-FUNKSJONER: ****************** // ************************************************************************* // Initierer/leser data om en ny kategori: Kategori::Kategori(int nr) : NumElement(nr) { // Oppgave 2C: Lag innmaten // Leser ALT om EN kategori fra fil: Kategori::Kategori(int nr, ifstream & inn) : NumElement(nr) { // Oppgave 2G: Lag innmaten void Kategori::display() { // Oppgave 2A: Lag innmaten void Kategori::display 2( // Oppgave 2B: Lag innmaten // Skriver alle HOVEDdata: // Skriver hoveddata og ALLE oppgavene: // Endrer status for en gitt oppgave: void Kategori::endreOppgaveStatus() { // Oppgave 2D: Lag innmaten // Skriver ALT om kategorien til fil: void Kategori::skrivTilFil(ofstream & ut) { // Oppgave 2F: Lag innmaten // ---------------------------------------------------------------------------- // Leser ALT om EN oppgave fra fil: Oppgave::Oppgave(int nr, ifstream & inn) : NumElement(nr) { // Oppgave 2G: Lag innmaten void Oppgave::display() { // Oppgave 2B: Lag innmaten // Skriver ALLE data: 7

void Oppgave::endreStatus() { // Oppgave 2D: Lag innmaten // Endrer oppgavens status: // Skriver ALT om oppgaven til fil: void Oppgave::skrivTilFil(ofstream & ut) { // Oppgave 2F: Lag innmaten // **************************************************************************** // ****************** DEFINISJON AV (GLOBALE) FUNKSJONER: ****************** // **************************************************************************** void skrivmeny() { // Skriver alle mulige menyvalg: cout << "\n\nfø LGENDE KOMMANDOER ER TILGJENGELIGE:" << "\n A - skriv hoveddataene om Alle kategoriene" << "\n K - skriv ALT om en gitt Kategori" << "\n N - Ny kategori" << "\n E - Endre en gitt oppgaves status" << "\n Q - Quit / avslutt"; char les() { // Leser og upcaser ett tegn: char ch; cin >> ch; cin.ignore(); return (toupper(ch)); // Leser et heltall mellom MIN og MAX: int les(const char* t, const int MIN, const int MAX) { int n; do { cout << '\t' << t << " (" << MIN << '-' << MAX << "): "; cin >> n; cin.ignore(); while (n < MIN n > MAX); return n; // Leser inn en tekst: void les(const char* t, char* s, const int LEN) { do { cout << '\t' << t << ": "; // Skriver ledetekst. cin.getline(s, LEN); // Leser inn tekst. while (strlen(s) == 0); // Sjekker at tekstlengden er ulik 0. void skrivaltomengittkategori() { // Oppgave 2B: Lag innmaten void nykategori() { // Oppgave 2C: Lag innmaten // Skriver ALT om en gitt kategori: // Legger inn en ny kategori: void endreoppgavestatus() { // Oppgave 2D og 2E: Lag innmaten // Endrer oppgaves status: void skrivtilfil() { // Oppgave 2F: Lag innmaten void lesfrafil() { // Oppgave 2G: Lag innmaten // Kategorier og oppgaver til fil: // Kategorier og oppgaver fra fil: 8