Avatar billede ferrari_brian Nybegynder
18. maj 2004 - 13:09 Der er 17 kommentarer og
1 løsning

ekstern programmering af program

Hej...

vi sidder og er ved at skulle lave en lommeregner man skal kunne programmere vha en txt-fil. vi har lavet de fleste funktioner, men vi kan ikke rigtig komme videre med dette:

:label    - Definerer en label.

JP label - Hopper til label, hvis indholdet af regneregisteret er større end 0.

JN label - Hopper til label, hvis indholdet af regneregisteret er mindre end 0.

JZ label - Hopper til label, hvis indholdet af regneregisteret er 0.

JMP label - Hop ubetinget til label.

resten er noget i retning af:

ADD n - Adderer indholdet i register n til regneregisteret. Resultatet gemmes i regneregisteret.

SUB n - Subtraherer indholdet af register n fra regneregisteret. Resultatet gemmes i regneregisteret.

og dette har vi lavet ...

nogen der har en ide til hvordan vi kan gøre dette ? self skal vi læse txt-filen igennem først og så søge efter labels ? og hvordan skal vi så lave jump-funktionerne ?

håber der er nogen der kan hjælpe...  ?

tak .. :D
Avatar billede ferrari_brian Nybegynder
18. maj 2004 - 13:10 #1
LET 2    ; gem tallet 2 i regneregisteret
STO 0    ; gem tallet 2 i register 0
LET 1    ; gem tallet 1 i regneregisteret
STO 1    ; gem tallet 1 i register 1
IN    ; brugeren indtaster et tal
STO 2    ; gem det indtastede tal i register 2
CMP 0    ; sammenlign det indtastede tal med tallet 2
JN SLUT    ; hvis det indtastede tal er mindre end 2 hoppes til SLUT
RCL 0    ; kopier tallet 2 til regneregisteret
OUT    ; udskriv tallet 2 på skærmen
ADD 1    ; adder tallet 1 til regneregisteret, resultatet er 3
:IGEN
STO 3    ; gem tallet i register 3
CMP 2    ; sammenlign tallet med brugerens indtastning
JP SLUT    ; hvis tallet er større end indtastningen hoppes til SLUT
PRIM 3    ; test om tallet er et primtal
JZ NEXT    ; er det ikke tilfældet hoppes til NEXT
RCL 3    ; hent tallet til regneregisteret
OUT    ; udskriv tallet på skærmen
:NEXT
ADD 0    ; adder 2 til tallet
JMP IGEN    ; hop til igen
:SLUT


- eksempel på program.txt
Avatar billede ferrari_brian Nybegynder
18. maj 2004 - 13:18 #2
jeg kan sende hovedkoden hvis det er ... men det vil blive for omfattende at sende det hele... :D
Avatar billede arne_v Ekspert
18. maj 2004 - 13:23 #3
Umiddelbart lyder det tiltalende at løbe filen igennem en gang
og gemme byte offset for alle labels sammen med label i en STL map og
så slå label op i den og seek'e til offset.
Avatar billede ferrari_brian Nybegynder
18. maj 2004 - 14:21 #4
okai... hvordan kan vi så lave denne liste... at køre filen igennem er ok ... men at lave listen og så finde ud af at læse hvor langt den skal hoppe tilbage... det kan vi ikke helt få til at du ? har du et eksempel eller noget ?
Avatar billede arne_v Ekspert
18. maj 2004 - 14:32 #5
Jeg kan måske godt lave et lille eksempel.
Avatar billede ferrari_brian Nybegynder
18. maj 2004 - 14:43 #6
class LabelInstruction : public Instruction
{
  char label;
public:
  LabelInstruction(Machine *ma, char *t) : Instruction(ma), label(*t) {}
  void execute();
};

void LabelInstruction::execute()
{
    cout << label << endl;
  ++mac->PC;
}class LabelInstruction : public Instruction
{
  char label;
public:
  LabelInstruction(Machine *ma, char *t) : Instruction(ma), label(*t) {}
  void execute();
};

void LabelInstruction::execute()
{
    cout << label << endl;
  ++mac->PC;
}

Og vi ønsker at opbevare label og PC i en liste og hvordan man for dem ud igen.
Avatar billede ferrari_brian Nybegynder
18. maj 2004 - 15:34 #7
liste = map :D
Avatar billede arne_v Ekspert
18. maj 2004 - 15:59 #8
Jeg kigger på det i aften
Avatar billede arne_v Ekspert
18. maj 2004 - 21:33 #9
test input:

:a
1
:b
2
:c
3

test program:

#include <iostream>
#include <fstream>
#include <string>
#include <map>

using namespace std;

static ifstream f;
static map<string,streampos> lblpos;

void load()
{
  string line;
  while(!f.eof())
  {
      getline(f,line);
      if(line[0]==':')
      {
          lblpos.insert(make_pair(line.substr(1, line.length()-1), f.tellg()));
      }
  }
  f.clear();
}

string find(string lbl)
{
    f.seekg(lblpos[lbl]);
    string line;
    getline(f,line);
    return line;
}

int main()
{
  f.open("seek.txt");
  load();
  cout << find("b") << endl;
  cout << find("c") << endl;
  cout << find("a") << endl;
  f.close();
  return 0;
}

test output:

2
3
1

(det virkede dog kun korrekt med halvdelen af mine C++ compilere)
Avatar billede bertelbrander Novice
18. maj 2004 - 23:12 #10
Hos mig virker det på to ud af tre, BorlandC++ og MS Visual V++ har ingen problemer.
På cygwin-gcc ser det ud til at f.tellg() flytter file pointeren!
Avatar billede arne_v Ekspert
18. maj 2004 - 23:25 #11
Man kan så prøve med:

#include <iostream>
#include <fstream>
#include <string>
#include <map>

const int CR = 1; // 1 with CR LF files (Windows), 0 with LF files (Unix)

using namespace std;

static ifstream f;
static map<string,streampos> lblpos;

void load()
{
  string line;
  while(!f.eof())
  {
      getline(f,line);
      if(line[0]==':')
      {
          lblpos.insert(make_pair(line.substr(1, line.length()-1-CR), f.tellg()));
      }
  }
  f.clear();
}

string find(string lbl)
{
    f.seekg(lblpos[lbl]);
    string line;
    getline(f,line);
    return line.substr(0, line.length()-CR);
}

int main()
{
  f.open("seek.txt", ios::binary);
  load();
  cout << find("b") << endl;
  cout << find("c") << endl;
  cout << find("a") << endl;
  f.close();
  return 0;
}
Avatar billede arne_v Ekspert
18. maj 2004 - 23:26 #12
Den kan jeg få til at virke med gcc mingw
Avatar billede bertelbrander Novice
18. maj 2004 - 23:48 #13
Det virker også med cygwin-gcc.
Det er, ikke overraskende, gcc der ikke kan finde ud af håndtere text filer rigtigt på DOS.

Jeg ville nok skriver load() sådan:
void load()
{
  string line;
  while(getline(f,line))
  {
      if(line[0]==':')
      {
          lblpos.insert(make_pair(line.substr(1, line.length()-1-CR), f.tellg()));
      }
  }
  f.clear();
}

Så undgår man at det ser ud somom den sidste linie bliver læst to gange.
Avatar billede ferrari_brian Nybegynder
19. maj 2004 - 08:31 #14
indtil videre tak... jeg vil lige afprøve det i programmet ... men arne_v regner jeg med skal have pointsene, men venter lige med at lukke indtil jeg er sikker på jeg har det jeg skal bruge...
Avatar billede ferrari_brian Nybegynder
25. maj 2004 - 16:18 #15
Hej... det virker fint for sig selv... men når vi bruger det på vores egen klasse giver den fejl idet vi bruger mange operator-overstyringer så dur det ikke med det using namespace std;

nogen forslag ?
Avatar billede arne_v Ekspert
25. maj 2004 - 16:22 #16
Der burde ikke være noget problem med at i bruger både operator overload og
using namespace std.

Men ellers kan I jo altid bruge std::ifstream i stedetfor ifstream.
Avatar billede ferrari_brian Nybegynder
25. maj 2004 - 17:01 #17
puha... nu får jeg 15 fejl istedet for 2... men fik vores til ikke at brokke over using namespace std; ...

er ved at løbe tør for inspiration til hvordan det skal virke... for den får flere og flere fejl... men hva... den skal nok komme til at køre
Avatar billede ferrari_brian Nybegynder
25. maj 2004 - 22:43 #18
tak for hjælpen... vi fik det ikke helt til at virke... men vi har ikke for meget mere tid så det bliver nedprioriteret for nu... måske senere ... :)

mvh Brian
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester