Gå til innhold

Eksamen 2002-Kompilerer,men kjører ikke


Anbefalte innlegg

Hei.

Driver på og leser til eksamen i C++, og jobber med tidligere eksamener.

Oppgaven lyder som følger:

På en datafil ligger opplysninger om aktuelle oppdrag for installatørene/teknikerene i en teknisk bedrift . De første tre oppgavene ser slik ut:

Institutt for datateknikk (NTNU)
Installere nytt nettverk
1
Malvik Videregående skole
Installasjon av Linux tjenermaskin og klienter
1
Malvik kommune
Installasjon av trådløst nettverk 
2

Det er tre linjer med data for hver oppgave. Første linje inneholder navn på oppgavestiller, andre linje tittel på oppgaven og tredje linje antall teknikere/installatører oppgaven er beregnet for. 

Fra eksemplet over leser vi at oppgave nr 2 er gitt av Malvik Videregående skole, tittelen er  “Installasjon av Linux tjenermaskin og klienter " og den er beregnet på 1 installatør.

Oppgavene har nummer gitt etter den rekkefølgen de ligger i. Oppgaver som allerede er lagt inn skal ikke kunne fjernes.

Du skal lage et program for vedlikehold av denne filen. OBS: Programmet skal begynne med å lese alle dataene inn i tre parallelle tabeller.

Programmet skal være menystyrt og tilby følgende muligheter:
•	Finn antall registrerte oppgaver.
•	Registrer en ny oppgave. Den nye oppgaven skal legges inn bakerst.
•	Endre tittelen til en oppgave. Brukeren skal oppgi oppgavens nummer.
•	Skriv ut alle oppgavene.
•	Skriv ut alle oppgavene som et bestemt firma tilbyr.

Ved bedømmingen av denne oppgaven blir det lagt vekt på hvordan du deler programmet opp i funksjoner. Riktig hovedprogram med korrekte funksjonskall er viktigere enn programmeringsdetaljer på laveste nivå.

Om du ikke rekker å programmere alle detaljer, skisser hva du mener ved hjelp av pseudokode (eller flytskjema). Du behøver ikke å ta hensyn til at data som leses fra brukeren eller fra datafilen kan inneholde feil.

Du må gjerne bruke funksjoner fra læreboka eller løsningsforslagene. Disse skal du ikke skrive. (Men husk å henvis til dem med f.eks. sidetall.)

 

Har så langt langt laget meg to metoder,- en som registrerer en ny oppgave og en som skriver til fil.

Programmet kompilerer uten feilmeldinger, men når jeg forsøker å kjøre programmet, får jeg disse feilmeldingene:

 

mai_2002 error LNK2019: unresolved external symbol "void __cdecl registrerNyOppgave(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,int *,int,int &)" (?registrerNyOppgave@@YAXPAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0PAHHAAH@Z) referenced in function _main

 

og

 

mai_2002 fatal error LNK1120: 1 unresolved externals

 

 

 

Her er koden min:

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

const string filnavn = "register.dat";

const int maxAntOppdrag = 100;


void registrerNyOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int &antallRegistrerteOppdrag); // Inn/Ut

void skrivTilFil(string *oppgavestiller,    // Inn
    string *tittel,      // Inn
    int *antTeknikkere,    	// Inn	
    int antallRegistrerteOppdrag);  	// Inn






int main() {

int antallRegistrerteOppdrag = 0;

//Oppretter de tre tabellene
string oppgavestiller[maxAntOppdrag];
string tittel[maxAntOppdrag];
int antTeknikkere[maxAntOppdrag];


//Registrerer et oppdrag
registrerNyOppgave(oppgavestiller, tittel, antTeknikkere, maxAntOppdrag, antallRegistrerteOppdrag); 

//Skriver oppdraget til fil
skrivTilFil(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

return 0;
}


//Metode som registrerer et nyttoppdrag
void registrerNyOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int antallRegistrerteOppdrag) {	// Inn/Ut
string oppgaveStiller;
string oppgaveTittel;
string antallTeknikkere;

cout << "Oppgavestiller: ";
getline(cin, oppgaveStiller);

cout << "Oppgavetittel: ";
getline(cin, oppgaveTittel);

cout << "Antall Teknikkere: ";
getline(cin, antallTeknikkere);
int antTek = atoi(antallTeknikkere.c_str());

//Registrerer det nye oppdraget i tabellene
oppgavestiller[antallRegistrerteOppdrag]    = oppgaveStiller;
tittel[antallRegistrerteOppdrag]            = oppgaveTittel;
antTeknikkere[antallRegistrerteOppdrag]     = antTek;

antallRegistrerteOppdrag++;

}



     
//Metode som skriver oppdrag til fil
void skrivTilFil(string *oppgavestiller,
    string *tittel,
    int *antTeknikkere,
    int antallRegistrerteOppdrag) {

   ofstream fil;
fil.open(filnavn.c_str(), ios::app);
   
for(int i = 0; i < antallRegistrerteOppdrag; i++) {
 fil << oppgavestiller[i] << endl;
 fil << tittel[i]   << endl;
 fil << antTeknikkere[i]  << endl;
}
fil.close();
}

 

 

 

Noen som ser hva som er galt?

Takker for all hjelp. :)

Lenke til kommentar
Videoannonse
Annonse

Ok. Hørtes ikke så dumt ut nei.

 

Er med unntak av funksjonen registrerNyOppgave() og et lite menysystem, ferdig med programmet.

Får fortsatt den sammen feilmeldinga hvis jeg bruker registrerNyOppgave(), men det fungerer som det skal hvis man registrerer data mauelt,- eks

 

oppgavestiller[0] = "NTNU";

tittel[0] = "Nytt nettverk";

antTeknikkere[0] = 1;

 

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

const string filnavn = "register.dat";

const int maxAntOppdrag = 100;


void registrerNyOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int &antallRegistrerteOppdrag); // Inn/Ut

void skrivTilFil(string *oppgavestiller,    // Inn
    string *tittel,      // Inn
    int *antTeknikkere,    	// Inn	
    int antallRegistrerteOppdrag);  	// Inn


void SkrivUtAlleOppgavene(string *oppgavestiller,  //Inn
       string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
       int antallRegistrerteOppdrag);//Inn

void endreTittel(string *oppgavestiller,  //Inn
    string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
    int antallRegistrerteOppdrag); //Inn

void skrivUtEtFirmasOppdrag(string *oppgavestiller,  	//Inn
         string *tittel,    	//Inn
     	int *antTeknikkere,    //Inn
     	int antallRegistrerteOppdrag);	//Inn

void lesInnFraFil(const string filnavn,    //Inn
     string *oppgavestiller,  	//Ut
     string *tittel,    	//Ut
     int *antTeknikkere,    //Ut
     int &antallRegistrerteOppdrag);	//Ut


int main() {

int antallRegistrerteOppdrag = 0;

//Oppretter de tre tabellene
string oppgavestiller[maxAntOppdrag];
string tittel[maxAntOppdrag];
int antTeknikkere[maxAntOppdrag];


/*
oppgavestiller[0] = "NTNU";
tittel[0]    = "Nytt nettverk";
antTeknikkere[0]  = 1;
   
oppgavestiller[1] = "HIST";
tittel[1]    = "Ny skriver";
antTeknikkere[1]  = 1;
*/

//Registrerer et oppdrag
registrerNyOppgave(oppgavestiller, tittel, antTeknikkere, maxAntOppdrag, antallRegistrerteOppdrag); 


SkrivUtAlleOppgavene(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);


return 0;
}


//Metode som registrerer et nyttoppdrag
void registrerNyOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int antallRegistrerteOppdrag) {	// Inn/Ut
string oppgaveStiller;
string oppgaveTittel;
string antallTeknikkere;

cout << "Oppgavestiller: ";
getline(cin, oppgaveStiller);

cout << "Oppgavetittel: ";
getline(cin, oppgaveTittel);

cout << "Antall Teknikkere: ";
cin >> antallTeknikkere;

getline(cin, antallTeknikkere);
int antTek = atoi(antallTeknikkere.c_str());

//Registrerer det nye oppdraget i tabellene
oppgavestiller[antallRegistrerteOppdrag]    = oppgaveStiller;
tittel[antallRegistrerteOppdrag]            = oppgaveTittel;
antTeknikkere[antallRegistrerteOppdrag]     = antTek;

antallRegistrerteOppdrag++;

}

//Metode som leser fra fil, og legger inn tabellene
void lesInnFraFil(const string filnavn,    //Inn
     string *oppgavestiller,  	//Ut
     string *tittel,    	//Ut
     int *antTeknikkere,    //Ut
     int &antallRegistrerteOppdrag)	//Ut
{
ifstream fil;
fil.open(filnavn.c_str());


string innlest;
getline(fil, innlest);

int teller = 0;

while(!fil.eof()) {
 oppgavestiller[teller] = innlest;
 getline(fil, innlest);
 tittel[teller] = innlest;
 getline(fil, innlest);
 antTeknikkere[teller] = atoi(innlest.c_str());
 teller++;
 getline(fil, innlest);
}
antallRegistrerteOppdrag = teller;
}



     
//Metode som skriver oppdrag til fil
void skrivTilFil(string *oppgavestiller,
    string *tittel,
    int *antTeknikkere,
    int antallRegistrerteOppdrag) {

   ofstream fil;
fil.open(filnavn.c_str(), ios::app);
   
for(int i = 0; i < antallRegistrerteOppdrag; i++) {
 fil << oppgavestiller[i] << endl;
 fil << tittel[i]   << endl;
 fil << antTeknikkere[i]  << endl;
}
fil.close();
}


//Metode som skriver ut alle oppgavene til skjermen
void SkrivUtAlleOppgavene(string *oppgavestiller,  //Inn
       string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
       int antallRegistrerteOppdrag) //Inn
{
for (int i=0; i < antallRegistrerteOppdrag; i++){
 cout << "OPPGAVE " << i << endl;
 cout << oppgavestiller[i] << endl;
 cout << tittel[i] << endl;
 cout << antTeknikkere[i] << endl << endl;
}
}


//Metode som skriver ut antall registrerte oppgaver
void finnAntallRegistrerteOppgaver(int antallRegistrerteOppdrag) {
cout << "Antall registrerte oppdrag: " <<  antallRegistrerteOppdrag;
}



//Metode som endrer tittelen på et oppdrag
void endreTittel(string *oppgavestiller,  //Inn
    string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
    int antallRegistrerteOppdrag)  //Inn
{
SkrivUtAlleOppgavene(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

int nummer;
string nyTittel;

cout << "Velg nummeret på den oppgaven du vil endre tittel på: ";
cin >> nummer;
cin.ignore();

cout << "Ny tittel: ";
getline(cin,nyTittel);

tittel[nummer] = nyTittel;
}

void skrivUtEtFirmasOppdrag(string *oppgavestiller,  	//Inn
         string *tittel,    	//Inn
     	int *antTeknikkere,    //Inn
     	int antallRegistrerteOppdrag)	//Inn
{

string firmanavn;
cout << "Skriv inn firmanavn: ";
getline(cin, firmanavn);

for(int i = 0; i < antallRegistrerteOppdrag; i++) {
 if(oppgavestiller[i] == firmanavn) {
 	cout << oppgavestiller[i] << endl;
 	cout << tittel[i] << endl;
 	cout << antTeknikkere[i] << endl;
 }
 else cout << "Ingen firma med det navnet." << endl;
}
}

Lenke til kommentar

På deklarasjonen av registrerNyOppgave, er det siste argumente en referanse, men det er den ikke i definisjonen. Derfor finner ikke kompilatoren definisjonen av en funksjon, og gir deg en linker-feil.

undefined reference to `registrerNyOppgave(std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, int*, int, int&)'

Udefinert referanse til funksjonen 'registerNyOppgave(std::basic_string<char, std::char_traits<char>, std::allocator<char> >* std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, int*, int, int&) == finner ikke definisjonen av funksjonen registerNyOppgave.

 

(Forresten, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >" er bare en såkalt typedef, eller, et annet navn for std::string. Så, std::basic_string<char, std::char_traits<char>, std::allocator<char> > og std::string er akkurat samme type.)

 

:)

Lenke til kommentar
Finnes det flere slike oppgaver fra høgskoler?

Og kan du gi link?

5317463[/snapback]

Sendt PM.

 

 

På deklarasjonen av registrerNyOppgave, er det siste argumente en referanse, men det er den ikke i definisjonen. Derfor finner ikke kompilatoren definisjonen av en funksjon, og gir deg en linker-feil.

Tusen takk for hjelpa. :)

Ikke første gang jeg gjør en slik feil. :blush:

 

 

Dette kræsjer først når du kjører programmet?

 

Kompilatoren (linkeren) burde sagt fra om dette!

Hvilken kompilator bruker du?

5317749[/snapback]

Bruker Visual C++.

Mulig jeg ordla meg litt feil her men.. Skal forklare hva jeg mente. Bruker

 

ctrl + F7 - for å kompilere.

ctrl + F5 - for å kjøre programmet.

 

Mulig det burde gjøres på en annen måte, og at komilatoren da hadde varslet fra om feilen. :hmm:

Lenke til kommentar

Ok. Da er programmet, med et lite menysystem "up and running".

Det fungerer desverre ikke helt som det skal enda, noe som sier meg at jeg har litt trøbbel med getline() og cin. :hmm:

 

Problemet er hvis jeg bruker menysystemet mitt, og forsøker å registrere en ny oppgave, så går det ikke.

"Oppgavestiller: Oppgavetittel:" - blir skrevet til skjermen.

Hvis jeg ikke bruker menysystemet, men benytter metoden "registrerNyOppgave()" direkte, så fungerer registreringen som den skal.

 

Hadde et lignende problem med metoden skrivUtEtFirmasOppdrag(), men løste det ved å bytte ut getline() med cin. Dette er Ikke en god løsning, da navnet kan bestå av flere navn, og da vil ikke programmet fungere. :dontgetit:

 

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

const string filnavn = "register.dat";

const int maxAntOppdrag = 100;


void registrerNyOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int &antallRegistrerteOppdrag); // Inn/Ut

void skrivTilFil(string *oppgavestiller,    // Inn
    string *tittel,      // Inn
    int *antTeknikkere,    	// Inn	
    int antallRegistrerteOppdrag);  	// Inn


void SkrivUtAlleOppgavene(string *oppgavestiller,  //Inn
       string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
       int antallRegistrerteOppdrag);//Inn

void endreTittel(string *oppgavestiller,  //Inn
    string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
    int antallRegistrerteOppdrag); //Inn

void skrivUtEtFirmasOppdrag(string *oppgavestiller,  	//Inn
         string *tittel,    	//Inn
     	int *antTeknikkere,    //Inn
     	int antallRegistrerteOppdrag);	//Inn

void lesInnFraFil(const string filnavn,    //Inn
     string *oppgavestiller,  	//Ut
     string *tittel,    	//Ut
     int *antTeknikkere,    //Ut
     int &antallRegistrerteOppdrag);	//Ut

void finnAntallRegistrerteOppgaver(int antallRegistrerteOppdrag); //Inn


int main() {

int antallRegistrerteOppdrag = 0;

//Oppretter de tre tabellene
string oppgavestiller[maxAntOppdrag];
string tittel[maxAntOppdrag];
int antTeknikkere[maxAntOppdrag];

//Starter programmet med å lese inn fra fil
lesInnFraFil(filnavn, oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

bool ferdig = false;

while(!ferdig) {
 cout << "Hva vil du gjore?" << endl;
 cout << "R:  Registrer Ny Oppgave" << endl;
 cout << "F:  Finn Antall Registrerte Oppgaver" << endl;
 cout << "E:  Endre Tittel Paa Oppgave" << endl;
 cout << "S:  Skriv Alle Oppgver Til Skjermen" << endl;
 cout << "O:  Oppgaver Til Bestemt Firma" << endl;
 cout << "A:  AVSLUTT" << endl;

 char valg;
 cin >> valg;
 valg = toupper(valg);
 
 if(valg == 'R') {
 	registrerNyOppgave(oppgavestiller, tittel, antTeknikkere, maxAntOppdrag, antallRegistrerteOppdrag);
 }
 
 else if(valg == 'F') {
 	finnAntallRegistrerteOppgaver(antallRegistrerteOppdrag);
 }

 else if(valg == 'E') {
 	endreTittel(oppgavestiller,	tittel,	antTeknikkere,	antallRegistrerteOppdrag);
 }

 else if(valg == 'S') {
 	SkrivUtAlleOppgavene(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);
 }

 else if(valg == 'O') {
 	skrivUtEtFirmasOppdrag(oppgavestiller,	tittel,	antTeknikkere, antallRegistrerteOppdrag);
 }

 else if (valg == 'A') ferdig = true;

 else cout << "Ulovlig valg!" << endl;
}//while



//registrerNyOppgave(oppgavestiller, tittel, antTeknikkere, maxAntOppdrag, antallRegistrerteOppdrag);




//Avslutter programmet med å skrive til fil
skrivTilFil(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

return 0;
}


//Metode som registrerer et nyttoppdrag
void registrerNyOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int &antallRegistrerteOppdrag) {// Inn/Ut
string oppgaveStiller;
string oppgaveTittel;
string antallTeknikkere;

cout << "Oppgavestiller: ";
getline(cin, oppgaveStiller);

cout << "Oppgavetittel: ";
getline(cin, oppgaveTittel);

cout << "Antall Teknikkere: ";
getline(cin, antallTeknikkere);
int antTek = atoi(antallTeknikkere.c_str());

//Registrerer det nye oppdraget i tabellene
oppgavestiller[antallRegistrerteOppdrag]    = oppgaveStiller;
tittel[antallRegistrerteOppdrag]            = oppgaveTittel;
antTeknikkere[antallRegistrerteOppdrag]     = antTek;

antallRegistrerteOppdrag++;

}

//Metode som leser fra fil, og legger inn tabellene
void lesInnFraFil(const string filnavn,    //Inn
     string *oppgavestiller,  	//Ut
     string *tittel,    	//Ut
     int *antTeknikkere,    //Ut
     int &antallRegistrerteOppdrag)	//Ut
{
ifstream fil;
fil.open(filnavn.c_str());


string innlest;
getline(fil, innlest);

int teller = 0;

while(!fil.eof()) {
 oppgavestiller[teller] = innlest;
 getline(fil, innlest);
 tittel[teller] = innlest;
 getline(fil, innlest);
 antTeknikkere[teller] = atoi(innlest.c_str());
 teller++;
 getline(fil, innlest);
}
antallRegistrerteOppdrag = teller;
}



     
//Metode som skriver oppdrag til fil
void skrivTilFil(string *oppgavestiller,
    string *tittel,
    int *antTeknikkere,
    int antallRegistrerteOppdrag) {

   ofstream fil;
//fil.open(filnavn.c_str(), ios::app); //Bruker ikke append, pga at det blir dobbelt opp registrert
   
fil.open(filnavn.c_str());
for(int i = 0; i < antallRegistrerteOppdrag; i++) {
 fil << oppgavestiller[i] << endl;
 fil << tittel[i]   << endl;
 fil << antTeknikkere[i]  << endl;
}
fil.close();
}


//Metode som skriver ut alle oppgavene til skjermen
void SkrivUtAlleOppgavene(string *oppgavestiller,  //Inn
       string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
       int antallRegistrerteOppdrag) //Inn
{
for (int i=0; i < antallRegistrerteOppdrag; i++){
 cout << "OPPGAVE " << i << endl;
 cout << oppgavestiller[i] << endl;
 cout << tittel[i] << endl;
 cout << antTeknikkere[i] << endl << endl;
}
}


//Metode som skriver ut antall registrerte oppgaver
void finnAntallRegistrerteOppgaver(int antallRegistrerteOppdrag) {
cout << "Antall registrerte oppdrag: " <<  antallRegistrerteOppdrag << endl;
}



//Metode som endrer tittelen på et oppdrag
void endreTittel(string *oppgavestiller,  //Inn
    string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
    int antallRegistrerteOppdrag)  //Inn
{
SkrivUtAlleOppgavene(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

int nummer;
string nyTittel;

cout << "Velg nummeret på den oppgaven du vil endre tittel på: ";
cin >> nummer;
cin.ignore();

cout << "Ny tittel: ";
getline(cin,nyTittel);

tittel[nummer] = nyTittel;
}

//Skriver ut oppgaver registrert på et bestemt firma
void skrivUtEtFirmasOppdrag(string *oppgavestiller,  	//Inn
         string *tittel,    	//Inn
     	int *antTeknikkere,    //Inn
     	int antallRegistrerteOppdrag)	//Inn
{

string firmanavn;
cout << "Skriv inn firmanavn: ";
//getline(cin, firmanavn);
cin >> firmanavn;
for(int i = 0; i < antallRegistrerteOppdrag; i++) {
 if(oppgavestiller[i] == firmanavn) {
 	cout << oppgavestiller[i] << endl;
 	cout << tittel[i] << endl;
 	cout << antTeknikkere[i] << endl;
 }
 //else cout << "Ingen firma med det navnet." << endl;
}

}

 

 

Noen forslag?

Lenke til kommentar

Når du leser menyen så leser du inn char. Når du skriver inn et valg, så må du skrive inn ønsket tegn + enter. Det vil si at tegner for enter ligger igjen på instreamen til nete gang du leser fra cin. Når programmet spør om Oppgavestiller, så vil det lese entertegnet, og tolke det som hele string'en.

 

En løsning er å lese inn til en string også når du leser i menyen, og så bare sjekke første tegn i stringen og forkaste resten.

 

Edit:

Eller du kan sette inn en cin.clear() før du begynner å lese fra cin. Litt usikker på hva mer clear() gjør, men det burde i hvertfall funke her.

Endret av JBlack
Lenke til kommentar
Når du leser menyen så leser du inn char. Når du skriver inn et valg, så må du skrive inn ønsket tegn + enter. Det vil si at tegner for enter ligger igjen på instreamen til nete gang du leser fra cin. Når programmet spør om Oppgavestiller, så vil det lese entertegnet, og tolke det som hele string'en.

 

En løsning er å lese inn til en string også når du leser i menyen, og så bare sjekke første tegn i stringen og forkaste resten.

5318296[/snapback]

 

Takk for hjelpa, JBlack.

Etter å ha endret fra char til string i menyen, så fungerer det som det skal. :yes:

Skal prøve å "utvide" programmet med flere metoder nå.

Siste innspurt før eksamen i morgen, og samtlige tidligere eksamener har en relativt stor oppgave som omhandler skriving/lesing til fil. (Håper bare det ikke blir binær-filer....)

 

For ev. interesserte ser programmet nå slik ut:

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

const string filnavn = "register.dat";

const int maxAntOppdrag = 100;


void registrerNyOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int &antallRegistrerteOppdrag); // Inn/Ut

void skrivTilFil(string *oppgavestiller,    // Inn
    string *tittel,      // Inn
    int *antTeknikkere,    	// Inn	
    int antallRegistrerteOppdrag);  	// Inn


void SkrivUtAlleOppgavene(string *oppgavestiller,  //Inn
       string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
       int antallRegistrerteOppdrag);//Inn

void endreTittel(string *oppgavestiller,  //Inn
    string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
    int antallRegistrerteOppdrag); //Inn

void skrivUtEtFirmasOppdrag(string *oppgavestiller,  	//Inn
         string *tittel,    	//Inn
     	int *antTeknikkere,    //Inn
     	int antallRegistrerteOppdrag);	//Inn

void lesInnFraFil(const string filnavn,    //Inn
     string *oppgavestiller,  	//Ut
     string *tittel,    	//Ut
     int *antTeknikkere,    //Ut
     int &antallRegistrerteOppdrag);	//Ut

void finnAntallRegistrerteOppgaver(int antallRegistrerteOppdrag); //Inn


int main() {

int antallRegistrerteOppdrag = 0;

//Oppretter de tre tabellene
string oppgavestiller[maxAntOppdrag];
string tittel[maxAntOppdrag];
int antTeknikkere[maxAntOppdrag];

//Starter programmet med å lese inn fra fil
lesInnFraFil(filnavn, oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

bool ferdig = false;

while(!ferdig) {
 cout << "Hva vil du gjore?" << endl;
 cout << "R:  Registrer Ny Oppgave" << endl;
 cout << "F:  Finn Antall Registrerte Oppgaver" << endl;
 cout << "E:  Endre Tittel Paa Oppgave" << endl;
 cout << "S:  Skriv Alle Oppgver Til Skjermen" << endl;
 cout << "O:  Oppgaver Til Bestemt Firma" << endl;
 cout << "A:  AVSLUTT" << endl;

 string valg;
 getline(cin, valg);
 //cin >> valg;
 
 char tegnEn   = valg[0];
 char tegnNrEn      = toupper(tegnEn);


 
 if(tegnNrEn == 'R') {
 	registrerNyOppgave(oppgavestiller, tittel, antTeknikkere, maxAntOppdrag, antallRegistrerteOppdrag);
 }
 
 else if(tegnNrEn == 'F') {
 	finnAntallRegistrerteOppgaver(antallRegistrerteOppdrag);
 }

 else if(tegnNrEn == 'E') {
 	endreTittel(oppgavestiller,	tittel,	antTeknikkere,	antallRegistrerteOppdrag);
 }

 else if(tegnNrEn == 'S') {
 	SkrivUtAlleOppgavene(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);
 }

 else if(tegnNrEn == 'O') {
 	skrivUtEtFirmasOppdrag(oppgavestiller,	tittel,	antTeknikkere, antallRegistrerteOppdrag);
 }

 else if (tegnNrEn == 'A') ferdig = true;

 else cout << "Ulovlig valg!" << endl;
}//while



//registrerNyOppgave(oppgavestiller, tittel, antTeknikkere, maxAntOppdrag, antallRegistrerteOppdrag);




//Avslutter programmet med å skrive til fil
skrivTilFil(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

return 0;
}


//Metode som registrerer et nyttoppdrag
void registrerNyOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int &antallRegistrerteOppdrag) {// Inn/Ut
string oppgaveStiller;
string oppgaveTittel;
string antallTeknikkere;

cout << "Oppgavestiller: ";
getline(cin, oppgaveStiller);

cout << "Oppgavetittel: ";
getline(cin, oppgaveTittel);

cout << "Antall Teknikkere: ";
getline(cin, antallTeknikkere);
int antTek = atoi(antallTeknikkere.c_str());

//Registrerer det nye oppdraget i tabellene
oppgavestiller[antallRegistrerteOppdrag]    = oppgaveStiller;
tittel[antallRegistrerteOppdrag]            = oppgaveTittel;
antTeknikkere[antallRegistrerteOppdrag]     = antTek;

antallRegistrerteOppdrag++;

}

//Metode som leser fra fil, og legger inn tabellene
void lesInnFraFil(const string filnavn,    //Inn
     string *oppgavestiller,  	//Ut
     string *tittel,    	//Ut
     int *antTeknikkere,    //Ut
     int &antallRegistrerteOppdrag)	//Ut
{
ifstream fil;
fil.open(filnavn.c_str());


string innlest;
getline(fil, innlest);

int teller = 0;

while(!fil.eof()) {
 oppgavestiller[teller] = innlest;
 getline(fil, innlest);
 tittel[teller] = innlest;
 getline(fil, innlest);
 antTeknikkere[teller] = atoi(innlest.c_str());
 teller++;
 getline(fil, innlest);
}
antallRegistrerteOppdrag = teller;
}



     
//Metode som skriver oppdrag til fil
void skrivTilFil(string *oppgavestiller,
    string *tittel,
    int *antTeknikkere,
    int antallRegistrerteOppdrag) {

   ofstream fil;
//fil.open(filnavn.c_str(), ios::app); //Bruker ikke append, pga at det blir dobbelt opp registrert
   
fil.open(filnavn.c_str());
for(int i = 0; i < antallRegistrerteOppdrag; i++) {
 fil << oppgavestiller[i] << endl;
 fil << tittel[i]   << endl;
 fil << antTeknikkere[i]  << endl;
}
fil.close();
}


//Metode som skriver ut alle oppgavene til skjermen
void SkrivUtAlleOppgavene(string *oppgavestiller,  //Inn
       string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
       int antallRegistrerteOppdrag) //Inn
{
for (int i=0; i < antallRegistrerteOppdrag; i++){
 cout << "OPPGAVE " << i << endl;
 cout << oppgavestiller[i] << endl;
 cout << tittel[i] << endl;
 cout << antTeknikkere[i] << endl << endl;
}
}


//Metode som skriver ut antall registrerte oppgaver
void finnAntallRegistrerteOppgaver(int antallRegistrerteOppdrag) {
cout << "Antall registrerte oppdrag: " <<  antallRegistrerteOppdrag << endl;
}



//Metode som endrer tittelen på et oppdrag
void endreTittel(string *oppgavestiller,  //Inn
    string *tittel,    //Inn
       int *antTeknikkere,  	//Inn
    int antallRegistrerteOppdrag)  //Inn
{
SkrivUtAlleOppgavene(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

int nummer;
string nyTittel;

cout << "Velg nummeret på den oppgaven du vil endre tittel på: ";
cin >> nummer;
cin.ignore();

cout << "Ny tittel: ";
getline(cin,nyTittel);

tittel[nummer] = nyTittel;
}

//Skriver ut oppgaver registrert på et bestemt firma
void skrivUtEtFirmasOppdrag(string *oppgavestiller,  	//Inn
         string *tittel,    	//Inn
     	int *antTeknikkere,    //Inn
     	int antallRegistrerteOppdrag)	//Inn
{

string firmanavn;
cout << "Skriv inn firmanavn: ";
getline(cin, firmanavn);
//cin >> firmanavn;
for(int i = 0; i < antallRegistrerteOppdrag; i++) {
 if(oppgavestiller[i] == firmanavn) {
 	cout << oppgavestiller[i] << endl;
 	cout << tittel[i] << endl;
 	cout << antTeknikkere[i] << endl;
 }
 //else cout << "Ingen firma med det navnet." << endl;
}

}

Lenke til kommentar
Edit:

Eller du kan sette inn en cin.clear() før du begynner å lese fra cin. Litt usikker på hva mer clear() gjør, men det burde i hvertfall funke her.

5318296[/snapback]

 

Har ikke forsøkt det, men har funnet en annen måte å gjøre det på om man ønsker å bruke char i menyen.

-->

Bruk cin.ignore() etter å lest inn menyvalget

 

char valg;
cin >> valg;
cin.ignore();

char tegnNrEn      = toupper(valg);

if(tegnNrEn == 'R') {
  ......

Lenke til kommentar

Problemet med ignore(), peek(), get, getline() osv er at de henger og venter dersom det ikke er flere tegn igjen på cin. Så man kan ikke bruke dem i en løkke og lese til cin er tom.

 

Dermed må man vite hvor mange ekstra tegn/linjer som ligger og venter i cin. Om du bruker din metode, så kan du riskiere at bruker trykker "rr"+ enter. Da vil ignore() plukke opp r nummer to, og enter vil bli liggende og gi problemer på neste input.

Lenke til kommentar

Skal ha det i bakhodet.. :)

 

Anyway,- driver på med en metode som skal slette en oppgave fra registeret.

//Metode som sletter en oppgave
void slettOppgave(string *oppgavestiller,  	// Inn/Ut
     string *tittel,    	// Inn/Ut
     int *antTeknikkere,    // Inn/Ut
     int maxAntOppdrag,    // Inn
     int &antallRegistrerteOppdrag)    // Inn/Ut
{
cout << "Registrerte Oppgaver: " << endl;
SkrivUtAlleOppgavene(oppgavestiller, tittel, antTeknikkere, antallRegistrerteOppdrag);

int oppgaveNummer;
cout << "Skriv inn nummeret paa oppgaven du vil slette: ";
cin >> oppgaveNummer;
cin.ignore();

if(oppgaveNummer <= antallRegistrerteOppdrag) {
 oppgavestiller[oppgaveNummer] = "";
 tittel[oppgaveNummer]         = "";
 antTeknikkere[oppgaveNummer]  = 0;
 
 antallRegistrerteOppdrag--;
}

else cout << "Feil nummer!" << endl;
}

 

Den fungerer faktsisk hvis man sletter den siste oppgaven i tabellene, men hvis man prøver å slette noen andre, så blir det bare tul... :cry:

 

Dette var ikke endel av oppgaven, men tenkte det kunne være kjekt å lære seg.

 

En tom tekststreng kan settes slik: "" - ikke sant?

Men hva med en "tom" int ? Det blir nok ikke riktig slik som jeg har gjort det,

antTeknikkere[oppgaveNummer] = 0

0 er jo en verdi.

Hva er betegnelsen for "ingen verdi" ?

 

Takknemlig for all hjelp. :)

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...