[C++] string vs int

Pagina: 1
Acties:

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 28-08 08:01
Met de volgende template beschrijf ik een
eenvoudige rij die altijd gesorteerd is van
klein naar groot:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <string>

template <class K>

class mijnVector {

      public:
       mijnVector();
       void voegToe(K element);
       void printRij();
       void verdubbelRij();
       void verschuifRij(int i, int t);
 
      private:
       int teller;
       int grootte;
       int index;
       K rij[10];
          
};

template <class K>
 mijnVector<K>:: mijnVector() {
  teller = 0;
  grootte = 10;
  index = 0;
 }
 
template <class K>
 void mijnVector<K>:: voegToe(K element) {
  
  //kijken waar het element moet komen
  while(element > rij[index]) {
     index++;
  }
  
  //kijken of er plaats genoeg is
  if (index > grootte) {
   grootte = grootte * 2;
   teller++;
   verdubbelRij();
   rij[index] = element;
  }
  else {
   //kijken of we moeten verschuiven
   teller++;
   if (index < teller) {
    verschuifRij(index,teller);
    rij[index] = element;
   }
  
  }
  
 }

template <class K>
 void mijnVector<K>:: printRij() {
  for (int i = 0; i < teller; i++) {
   cout << rij[i] << "\n";
  }
 }

template <class K>
 void mijnVector<K>:: verdubbelRij() {
  K kopie[grootte];
  
  for (int i = 0; i < teller; i++) {
   kopie[i] = rij[i];
  }
  
  K rij[grootte];
  
  for (int i = 0; i < teller; i++) {
   rij[i] = kopie[i];
  }    
 }

template <class K>
 void mijnVector<K>:: verschuifRij(int i, int t) {
  //kijken of er nog plaats is om te verschuiven
  if (t >= grootte) {
   verdubbelRij();
  }
  
  for(int j = grootte; j > i; j--) {
   rij[j] = rij[j-1];
  }
 
 }


Deze code werkt goed als ik in mijn testprogrammatje
alleen ints verwerk. Maak ik een rij om strings toe
te voegen dan crasht mijn programma.

Ik vermoed dat de fout hier zit:
code:
1
2
3
4
  //kijken waar het element moet komen
  while(element > rij[index]) {
     index++;
  }

Dit stukje code is onderdeel van de methode voegToe(K element).

Ik weet dat je strings net zo goed kan vergelijken met <, > en =
(zoals ints dus), maar ook dat er een methode compareTo() bestaat
in de klasse string. Als ik deze compareTo() zou gebruiken dan
zal mijn template niet meer werken met eender welk datatype.

Ook heb ik geprobeerd om te kijken naar de teller, en als deze teller
op 0 stond dat ik dan gewoon het element op index 0 zet in de rij.
Zo had ik altijd iets om mee te vergelijken dan dacht ik, maar mijn
programma blijft crashen.

Volgens mij zit het probleem dus gewoon in het feit dat ik geen lege
array kan vergelijken met een string maar wel met een int.

Zie ik dit fout? En hoe los ik dit probleempje op?

Clowns to the left of me, Jokers to the right


Verwijderd

lege array vergelijken met een string.
mmm even denken als basis geldt dat rij[0] wijst naar het eerste element van het array.

string is volgens mij geen zegswijze in c++ althans niet zoals in andere talen een string wordt bedoelt. Een string gezien als pointer naar een char*.

Even denken je wijst dus zal maar zeggen met een pointer naar een pointer (array->string) en het geval met de integer wijs je van een array naar een basisadres van een geheugenplekje voor de integer.

Je zult denk ik aan moeten geven welk item je uit het array je met welke array van chars* wilt vergelijken.

Klinkt allemaal een beetje wazig denk ik maar ik denk altijd hardop...

/me is still thinking

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 28-08 08:01
Ik heb even mijn code uitgebreid:

code:
1
2
3
4
5
6
7
8
9
10
//kijken waar het element moet komen
  if(teller = 0) {
   rij[0] = element;
   teller++;
  }
  else {
    while(element > rij[index]) {
     index++;
    }
  }


Mijn programma crasht echter nog altijd. Nochtans zit
er dus een element op index 0 in de array en kan er dus
vergeleken worden met een andere string.

Clowns to the left of me, Jokers to the right


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 23:57

mulder

ik spuug op het trottoir

Mijn app crasht net ook. Errormelding is wel handig!

(btw if (teller == 0) is het toch al ten eerste?)

oogjes open, snaveltjes dicht


  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 28-08 08:01
Mijn app crasht net ook. Errormelding is wel handig!
Ik wil graag een foutmelding geven maar het enige dat
verschijnt is een lullig windows venstertje dat zegt dat
er een foutenlogboek wordt gemaakt en daarna stopt mijn
programma gewoon.
(btw if (teller == 0) is het toch al ten eerste?)
Klopt, had ik nog niet gezien, maar het doet niets af aan
het crashen van mijn programma.

Clowns to the left of me, Jokers to the right


  • The End
  • Registratie: Maart 2000
  • Laatst online: 28-08 19:10

The End

!Beginning

Ja, wanneer stopt je vergelijking???
code:
1
2
3
4
//kijken waar het element moet komen
  while(element > rij[index]) {
     index++;
  }

index wordt dus uiteindelijk groter dan 9 (rij[10] element 0 tot 9) en dan chrashed je programma (vaak, soms heb je mazzel). Dit heet 'out of bounds'.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
Je vermoeden over de plaats waarop het mis gaat, was juist. Met een debugger was de fout zo gevonden (al schaam ik me een beetje dat ik het niet gewoon uit m'n hoofd zag).

Je while-lus wordt uitsluitend afgesloten als het nieuwe element groter is dan een van de bestaande elementen. Als je toevallig een element toe wil voegen dat groter is dan alle anderen tot nu toe (wat bij het eerste element altijd zo is) wordt index groter dan grootte en loop je buiten je array.

Ik snap trouwens niets van de rest van je code. Wat doet die index en waarom wordt die in de constructor op nul gezet? Wat wil je dan met je while-lus bereiken, want op deze manier wijst je index natuurlijk altijd buiten het geldige deel van de array (met indices onder teller). De naamgeving van je identifiers maakt het er ook niet eenvoudiger op.

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 28-08 08:01
Index dient dus om de juiste plaats in de array aan te geven

op basis van deze index zal mijn rij verdubbeld worden indien
nodig en alles vanaf deze index zal opgeschoven worden met
1 plaats

Ik zet deze op 0 in mijn constructor omdat ik logischerwijs wil
beginnen te kijken vanaf het 0de element in mijn array.

ik had misschien beter die debug functie gebruikt maar ik kan
hier nog niet echt mee overweg. C++ wordt bij ons gegeven
in het kader van 'zoek het zelf maar ff uit jonges'. Ik heb zelf
wel nog wat proberen te debuggen door lijntjes te printen in
mijn console zodanig dat ik kon nagaan wat wel werkte natuurlijk.

*zucht* denk dat Java meer mijn meug is ;)

nuja, bedankt voor de tips mensen, ik zal die lus nog eens onder
de loep nemen. (Toch vind ik het raar dat die lus wel goed werkt
met int waarden, daar heb ik nooit last gehad van out of bound fouten,
per slot van rekening kijk ik toch de index waarde na in mijn code
en neem gepaste maatregelen lijkt mij toch...)

_/-\o_

Clowns to the left of me, Jokers to the right


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 24-08 22:38
Vind jij een char * een string of vind jij een std::string een string ?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • The End
  • Registratie: Maart 2000
  • Laatst online: 28-08 19:10

The End

!Beginning

Kapoen schreef op 19 november 2002 @ 14:20:
index dient dus om de juiste plaats in de array aan te geven

op basis van deze index zal mijn rij verdubbeld worden indien
nodig en alles vanaf deze index zal opgeschoven worden met
1 plaats

ik zet deze op 0 in mijn constructor omdat ik logischerwijs wil
beginnen te kijken vanaf het 0de element in mijn array.
Dat doe je niet in jou code. De vergelijking komt voordat je kijkt of je array wel groot genoeg is.

code:
1
2
3
4
5
6
7
8
9
10
while(element > rij[index]) {
     index++;
  }
  
  //kijken of er plaats genoeg is <--------------------- HIERZO!!!!
  if (index > grootte) {
   grootte = grootte * 2;
   teller++;
   verdubbelRij();
   rij[index] = element;

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
Kapoen schreef op 19 november 2002 @ 14:20:
Index dient dus om de juiste plaats in de array aan te geven

op basis van deze index zal mijn rij verdubbeld worden indien
nodig en alles vanaf deze index zal opgeschoven worden met
1 plaats
Wat representeert je klasse dan? Ik dacht dat het simpelweg een geordende collectie was (vergelijkbaar met de standaard Vector klasse, maar dan zo, dat de elementen altijd gesorteerd ingevoegd worden).

Als dat inderdaad de bedoeling is, dan is er teveel fout aan je code om op te noemen en kun je misschien beter even op papier uittekenen hoe de boel moet werken (hoe je de interne lijst managed). Het grootte attribuut lijkt me trouwens niet zo nuttig, want je array weet al hoe groot 'ie is, maar dit terzijde.
ik had misschien beter die debug functie gebruikt maar ik kan
hier nog niet echt mee overweg. C++ wordt bij ons gegeven
in het kader van 'zoek het zelf maar ff uit jonges'. Ik heb zelf
wel nog wat proberen te debuggen door lijntjes te printen in
mijn console zodanig dat ik kon nagaan wat wel werkte natuurlijk.

*zucht* denk dat Java meer mijn meug is ;)
Ach ja, ergelijk is dat soort onderwijs (ik herken dat wel). Ik heb toch altijd het idee dat dat wel beter moet kunnen.

Los daarvan vind ik C++ vaak lastiger om goed te krijgen, maar fijner om mee te werken, juist omdat het goed te debuggen is. In theorie kan dat met Java ook natuurlijk, maar ik heb geen goede IDE daarvoor en dan ben ik altijd genoodzaakt te debuggen zoals jij dat nu ook doet: tussendoor allerlei debug info printen ("hier!", "weer hier!", "bla!", enzovoorts). Vergeleken met een 'echte' debug sessie kost die methode heel veel werk en levert het weinig accurate informatie op.

Jou code had ik gedebugt door 'm simpelweg te runnen en bij de crash de backtrace weer te geven; toen kwam ik direct op het goede punt uit. Even klikken op de variabele 'index' gaf de oplossing. Als ik dit in 1 keer had moeten vinden door het printen van debug-informatie bij de executie, had ik tientallen regels toe moeten voegen (als ik niet weet waar de fout zit, moet ik immers alles printen).
Toch vind ik het raar dat die lus wel goed werkt
met int waarden, daar heb ik nooit last gehad van out of bound fouten,
per slot van rekening kijk ik toch de index waarde na in mijn code
en neem gepaste maatregelen lijkt mij toch...
Met integers gaat het een stuk beter, omdat je dan misschien wel buiten je array leest, maar je interpreteert het geheugen wat je tegenkomt als integer. Zolang je in je 'eigen' geheugen blijft, gaat dit wel goed (je krijgt geen crash). Als je strings toevoegt, komen er gegevens in het geheugen te staan die pointerwaardes bevatten. De kans dat je een willekeurige pointerwaarde zonder problemen kan volgen, is wel heel klein.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:21

.oisyn

Moderator Devschuur®

Demotivational Speaker

overigens klopt er, afgezien van die te late check, geen zak van :)
je doet
C++:
1
2
3
4
5
6
7
  //kijken of er plaats genoeg is
if (index > grootte) {
   grootte = grootte * 2;
   teller++;
   verdubbelRij();
   rij[index] = element;
}


en in verdubbelRij staat:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class K>
 void mijnVector<K>:: verdubbelRij() {
  K kopie[grootte];
  
  for (int i = 0; i < teller; i++) {
   kopie[i] = rij[i];
  }
  
  K rij[grootte];
  
  for (int i = 0; i < teller; i++) {
   rij[i] = kopie[i];
  }    
 }


je maakt dus eerst de grootte groter, en daarna maak je 2 kopies. Eerst kopieer je grootte elementen naar kopie (waar je dus buiten je buffer treedt, want grootte is dan al 2* zo groot), en daarna declareer je een nieuwe buffer met de naam rij, en dan kopieer je alles van kopie naar rij

Maar de rij van de klasse blijft onaangepast, bovendien staat de grootte van die array vast (is altijd 10).

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 28-08 08:01
Ok ik ga het dus oplossen volgens deze principes:
klein voorbeeldje (heel simpel):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main() {
 int i = 0;
 string rij[3];
 string leeg = "";
 rij[0] = "a";
 rij[1] = "c";
 rij[2] = "b";
 
 while (rij[2] > rij[i]) {
  i++;
 }
 leeg = rij[i];
 rij[i] = rij[2];
 rij[2] = leeg;

 cout << rij[0] << "\n";
 cout << rij[1] << "\n";
 cout << rij[2] << "\n";
 system("pause");
}


Ik duw het nieuwste element sowieso op de laatst mogelijke index
Daarna kijk ik waar hij werkelijk moet komen. Als laatste stap hoef
ik alleen maar een eenvoudige methode te gebruiken die elementen
van plaats wisselt. (Dit voorbeeldje komt grosso modo overeen met
wat ik bedoel ;) )

bedankt voor de hulp mensen _/-\o_

Clowns to the left of me, Jokers to the right

Pagina: 1