Toon posts:

[C++] Oneindig invoer

Pagina: 1
Acties:
  • 278 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Bij het programmeren ben ik tegen een aantal problemen opgelopen.
Ik zoek een manier om een oneindige invoer van getallen in te kunnen voeren
en het daarna netjes onder elkaar in een tabelletje zet. Dit is natuurlijk maar
een voorbeeld van de vele mogelijkheden van oneindige invoer. tot zo ver heb ik
dit gedaan:

C++:
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
#include <iostream>
#include <iomanip>
using namespace std;

#define MAX 50

int main()
{

    int getallen[MAX+1];
    for ( int i=0;i < MAX +1;i++ )
    {
        getallen[i] = 0;
    }

    int invoer;
    
    cin >> invoer;

    while ( invoer !=0 )
    {
        getallen[invoer]++;
        cin >> invoer;
    }


    cout << setw(5) << "invoer";
    for ( i=0; i < MAX +1; i++)
    {
            cout << setw(5) << getallen[i];
        
    }



    return 0;

}



Moet er wel bij zeggen dat ik een beginnende programmeur ben. Dit heb ik uit een ander voorbeeld gehaald en een aantal aanpassingen hier aan de code gedaan.
Het compileerd wel maar werken? :(

Is er iemand die een beter voorbeeld heeft of ziet wat er hier fout zit ??

Bedankt.

Groeten,
D3vi1

[ Voor 7% gewijzigd door .oisyn op 21-09-2003 21:19 ]


  • dArtagnan
  • Registratie: Mei 2002
  • Laatst online: 15-07 20:09

dArtagnan

Een voor allen, allen voor een

Waar stopt het programma met werken? Druk je wel op 0 om te stoppen met invoeren?

[ Voor 107% gewijzigd door dArtagnan op 21-09-2003 21:00 ]


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 21-08 14:03

Robtimus

me Robtimus no like you

Dit kan behoorlijk fout gaan als invoer < 0 of > MAX is.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
Koraalduivel schreef op 21 September 2003 @ 20:56:
Waar stopt het programma met werken? Druk je wel op 0 om te stoppen met invoeren?
Als ik dit compileer en dit uitvoer gebeurt er dit:

ik voer de getallen in
1
3
6
8
54
4
0 toets 0 om af te sluiten en dan dit -->
invoer 0 1 0 1 1 0 1 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0Press any key to continue

[ Voor 21% gewijzigd door Verwijderd op 21-09-2003 21:03 ]


  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 00:19

Reptile209

- gers -

Verwijderd schreef op 21 september 2003 @ 20:53:
C++:
1
2
3
4
5
6
7
8
9
    int invoer;
    
    cin >> invoer;

    while ( invoer !=0 )
    {
        getallen[invoer]++;
        cin >> invoer;
    }
Als je dat nou eens verandert in:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
int invoer;

cin >> invoer;

i = 0;

while (invoer != 0)
{
  getallen[i] = invoer;
  cin >> invoer;
  i++;
}

Want nu ben je aan het tellen hoe vaak ieder getal voorkomt... en dat is precies wat je nu als uitvoer ziet... :)

Edit:
zet je code tussen [ code ] en [ /code ], is wat leesbaarder...
Bedankt.

Groeten,
D3vi1
Niet nodig, zie FAQ :)

[ Voor 16% gewijzigd door Reptile209 op 21-09-2003 21:17 ]

Zo scherp als een voetbal!


  • dArtagnan
  • Registratie: Mei 2002
  • Laatst online: 15-07 20:09

dArtagnan

Een voor allen, allen voor een

Er moet dan toch ook cin >> invoer; in de while-loop staan. Nu krijgt hij geen nieuwe invoer meer waardoor de loop oneindig is.

  • simon
  • Registratie: Maart 2002
  • Laatst online: 21-08 13:41
offtopic:
[coïtus met insecten modus]Even tussendoor, oneindige invoer? Alles is gelimiteerd, of je geheugen loopt vol, of je invoer is te groot voor een variabele... Kun je het eigenlijk zo groot mogelijke invoer noemen[/coïtus met insecten modus]

|>


  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 00:19

Reptile209

- gers -

Koraalduivel schreef op 21 September 2003 @ 21:11:
Er moet dan toch ook cin >> invoer; in de while-loop staan. Nu krijgt hij geen nieuwe invoer meer waardoor de loop oneindig is.
Jazeg, ik ga alles voorkauwen zeker :X
(idd vergeten... edit 'm wel ff :P)

Zo scherp als een voetbal!


Verwijderd

hahaha beter goed gejat dan slecht gemaakt zeggen ze wel is :+
maarre hij is druk bezig :9

Verwijderd

Topicstarter
Reptile209 schreef op 21 September 2003 @ 21:13:
[...]

Jazeg, ik ga alles voorkauwen zeker :X
(idd vergeten... edit 'm wel ff :P)
Ben ook niet dom natuurlijk })

maarem bedankt !!!!

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 00:19

Reptile209

- gers -

Verwijderd schreef op 21 September 2003 @ 21:18:
[...]
Ben ook niet dom natuurlijk })
maarem bedankt !!!!
Voor de leercurve: snap je ook wat er nou "fout" was aan je eerste ontwerp?

Zo scherp als een voetbal!


Verwijderd

Topicstarter
Verwijderd schreef op 21 September 2003 @ 21:16:
hahaha beter goed gejat dan slecht gemaakt zeggen ze wel is :+
maarre hij is druk bezig :9
Mjah kan ook beter hier posten dan wat aan jou vragen :-D
heb andwoord binnen 5 min. :P

Verwijderd

Topicstarter
Reptile209 schreef op 21 September 2003 @ 21:19:
[...]

Voor de leercurve: snap je ook wat er nou "fout" was aan je eerste ontwerp?
jah dit was ook de bedoeling met getallen[invoer]++;
hij telde het aantal keer dat een getal was ingevoerd niet waar door
ik alleen het laatste ingevoerde getal overhield 0 dus.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hoi, welkom op GoT
Lees eerst de verplichte kost, namelijk de algemene faq en P&W FAQ - De "quickstart"

Daar kun je onder andere lezen dat je code beter tussen [norml]
code:
1
...
tags of [code=[/]taal[norml]]...[/code][/] tags kunt plaatsen ;)

Verder inhoudelijk:
het is natuurlijk wel leuk zo, maar je zit altijd maar met een maximum aantal aan getallen. (Waarom gebruik je trouwens steeds MAX + 1 ipv gewoon MAX?). Misschien is het handiger om een soort van dynamische array te gebruiken. C++ levert hier een aantal klassen voor, zoals vector. Dan kun je gewoon een "oneindig" aantal aan ints toevoegen

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.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Simon schreef op 21 September 2003 @ 21:13:
offtopic:
[coïtus met insecten modus]Even tussendoor, oneindige invoer? Alles is gelimiteerd, of je geheugen loopt vol, of je invoer is te groot voor een variabele... Kun je het eigenlijk zo groot mogelijke invoer noemen[/coïtus met insecten modus]
Datgene wat volloopt is een technisch implementatie detail. Het ontwerp van het programma kan best zo opgezet worden dat het een oneindige invoer aankan. Dat er dan uitendelijk niet een oneindig aantal aan getallen behandeld kunnen worden ligt aan de onderliggende hardware, niet aan het programma.

Op de hedendaagse 80x86 processoren kun je bijvoorbeeld 'maar' 232 entries indexeren, en maar 232 / sizeof (int) entries addresseren, maar dat is puur door de compilatie voor een x86 processor. Als je het programma goed opzet dan is datzelfde programma gecompileerd op bijvoorbeeld een AMD64 ineens in staat op bij 264 te kunnen, zonder dat er iets is veranderd.

Bij het programma-ontwerp spreek je dus wel over oneindig

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.


Verwijderd

Topicstarter
Ik heb een aantal wijzigingen aangebracht in de code.

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
#include <iostream>
#include <iomanip>
using namespace std;

#define MAX 50

int main()
{
    int getallen[MAX];
    int invoer;
    int AANTAL = 0;

    for ( int i=0; i <= MAX;i++ )
    {
        getallen[i] = 0;
    }

    i = 0;

    while ( invoer != 0 )
    {
        cin >> invoer;
        getallen[i] = invoer;
        i++;
        AANTAL++;
    }

    for ( i=0; i <= AANTAL - 2 ; i++ )
    {
        cout << setw(5) << getallen[i] << "\n";
    }

    return 0;

}


Zo werkt hij maar na uitvoer van de ingevoerde getallen crashed het programma.
Iemand een idee waar dit aan kan liggen ???

[ Voor 8% gewijzigd door Verwijderd op 21-09-2003 22:47 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Daar heb je een debugger voor. Waar crasht ie precies? En wat zijn dan de waarden van de variabelen op die regel?

En als je geen goede debugger hebt kun je natuurlijk zelf ook wat diagnostische info uitputten naar je scherm

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.


  • _Squatt_
  • Registratie: Oktober 2000
  • Niet online
Verwijderd schreef op 21 september 2003 @ 22:46:
Zo werkt hij maar na uitvoer van de ingevoerde getallen crashed het programma.
Iemand een idee waar dit aan kan liggen ???
Een paar opmerkingen:

Als je een variabele declareert in een for() loop is de scope van die variabele alleen het stukje in de for() loop:
C++:
1
2
3
4
5
for ( int i = 0 ; i < MAX ; ++i) // hier declareren we 'i'
{
    // hier kunnen we 'i' gebruiken.
}
// hier is 'i' onbekend.

Mijn compiler geeft hier een error over, maar misschien heb jij een oudere, die het wel accepteert.

Verder is het gebruikelijk om #define'd constanten in hoofdletters te doen, en variabelen niet. Dus ik zou 'aantal' gebruiken in plaats van 'AANTAL', maar dit is meer voor duidelijkheid, dit veroorzaakt geen crash.

Als ik je programma iets aanpas krijg ik dit:
C++:
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
#include <iostream>
#include <iomanip>
using namespace std;

#define MAX 50

int main()
{
        int getallen[MAX];
        int invoer;                             // *1
        int aantal = 0;

        for ( int i=0; i <= MAX;i++ )
        {
                getallen[i] = 0;
        }

        // de 'i' variabele is niet nodig, want die telt precies
        // hetzelfde als 'aantal'.

        while ( invoer != 0 )                   // *2
        {
                cin >> invoer;
                getallen[aantal] = invoer;
                aantal++;
        }

        // Hier declareer ik een andere 'i', want de 'i' van de vorige
        // for() loop besttat hier niet.
        for ( int i=0; i <= aantal - 2 ; i++ )
        {
                cout << setw(5) << getallen[i] << "\n";
        }

        return 0;

}


Dit programma werkt hiet prima, maar het zou best niet kunnen werken. Waarom?
Bij '*1' declareer je 'int invoer', je geeft er geen waarde aan, dus 'invoer' heeft nu de waarde die toevallig op die plek in het geheugen staat.

Bij '*2' is de conditie voor je while() echter 'invoer != 0', wat gebeurt er nu als 'invoer' aan het begin van je programma toevallig de waarde '0' krijgt?

"He took a duck in the face at two hundred and fifty knots."


Verwijderd

Topicstarter
.oisyn schreef op 21 September 2003 @ 23:02:
Daar heb je een debugger voor. Waar crasht ie precies? En wat zijn dan de waarden van de variabelen op die regel?

En als je geen goede debugger hebt kun je natuurlijk zelf ook wat diagnostische info uitputten naar je scherm
Alles zou moeten werken het probleem is dus

Nadat ik alle getallen ingevoerd heb en 0 toets om de tabel weer te geven
dan geeft tie de uitvoer van de tabel en crashed met de melding:

De instructie op 0x004261fc verwijst naar het geheugen op 0xffffffe4. De lees- of
schrijfbewerking ("written") op het geheugen is mislukt.

Bij de debugger krijg ik hier een pijltje

code:
1
004261FC   mov         dword ptr [mainret],eax


zou dit aan Visual C++ liggen of is mijn code toch niet goed ??

Zal er gelijk maar bij zeggen dat ik nog nooit iets met de debugger heb gedaan :)

[ Voor 20% gewijzigd door Verwijderd op 21-09-2003 23:33 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sluit die disassembly window, en ga in de call stack zoeken naar de regel in jouw source waar hij crasht (meestal zie je die al als je de disassembly window sluit). Debuggen is toch wel iets wat je zelf onder de knie moet krijgen, daar gaan wij je niet bij helpen

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.


Verwijderd

Topicstarter
Zo werkt tie wel voor de geintreseerde:

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
#include <iostream>
#include <iomanip>
using namespace std;

#define MAX 50

int main()
{
    int getallen[MAX];
    int invoer;
    int aantal = 0;

    for ( int i = 0; i > MAX;i++ )
    {
        getallen[i] = 0;
    }

    while ( invoer != 0 )
    {
        cout << "Geef een getal:";
        cin >> invoer; 
        getallen[i] = invoer;
        i++;
        aantal++;
    }

    for ( i = 0; i <= aantal -1; i++ )
    {
        cout << "\n" << setw(5) << getallen[i];
    }


    return 0;

}



Later !

  • mafti
  • Registratie: Januari 2003
  • Laatst online: 11-11-2022

mafti

Kopyright Liberation Front

Erm,

er zit een "grote" fout in. je checkt nl. niet of de MAX al gepasseerd is. je gaat dus
op je 51ste element uit je array.
dat het werkt betekent uiteraard niet dat het een correct progje is.

er zijn natuurlijk vele alternatieven.
de snelste is natuurlijk dat je stop bij de (MAX-1)de element.

while (invoer != 0 && i<MAX)
{
[...]
}

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 21-08 14:03

Robtimus

me Robtimus no like you

Verwijderd schreef op 22 september 2003 @ 12:04:
Zo werkt tie wel voor de geintreseerde:
Hij zou niet eens mogen werken, tenzij je wat typo's hebt gemaakt
C++:
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
#include <iostream>
#include <iomanip>
using namespace std;

#define MAX 50

int main()
{
    int getallen[MAX];
    int invoer;
    int aantal = 0;

    for ( int i = 0; i > MAX;i++ )
    /*
     * deze loop wordt nooit uitgevoerd, want de conditie geldt nooit
     * (tenzij MAX < 0)
     */
    {
        getallen[i] = 0;
    }

    while ( invoer != 0 )
    {
        cout << "Geef een getal:";
        cin >> invoer; 
        getallen[i] = invoer;
        i++;
        /*
         * waarom gebruik je i nog steeds? Zoals Squatt al zei
         * kan aantal deze functie perfect overnemen. Verder
         * zou i niet eens gebruikt mogen worden wegens
         * ongeldige scope (i zou alleen binnen de eerste for
         * loop gebruikt mogen worden
         */
        aantal++;
    }

    for ( i = 0; i <= aantal -1; i++ )
    /*
     * i <= aantal-1 === i < aantal, dat laatste staat netter.
     * Weer die i zonder declaratie gebruikt
     */
    {
        cout << "\n" << setw(5) << getallen[i];
    }


    return 0;

}

[ Voor 29% gewijzigd door Robtimus op 22-09-2003 12:31 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • mafti
  • Registratie: Januari 2003
  • Laatst online: 11-11-2022

mafti

Kopyright Liberation Front

blijkbaar denkt visual c++ voor je mee ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ook heeft invoer een nog ongedefinieerde waarde op het moment dat je voor de eerste keer in de while lus gaat. Waarom je i gebruikt is mij ook een raadsel, destemeer omdat je ook nog een variabele aantal hebt die precies hetzelfde aangeeft.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <iomanip>
#include <vector>

int main ()
{
    std::vector<int> getallen;

    for (;;)
    {
        int invoer;
        std::cin >> invoer;
        if (!invoer)
           break;
        getallen.push_back (invoer);
    }

    for (std::vector<int>::iterator it = getallen.begin (); it != getallen.end (); ++it)
        std::cout << std::setw (5) << *it << std::endl;
}


En eigenlijk moet je de invoer nog controleren op juistheid (wat als je bijvoorbeeld een woord invoert?), maar dat laat ik over aan de TS :Y)

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.


Verwijderd

Zat er niet zo'n leuke bug in Visual Studio zodat "i" buiten de for loop nog steeds bruikbaar was?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nee, geen bug, een feature (en dat is geen grapje). De for-scope was niet altijd zoals ie nu is in de C++ standaard. En in de eerste versies van MSVC++ was die scope dus ook niet zo gedefinieerd. Later is het in de standaard veranderd (als ik me niet vergis), maar MS heeft het erin laten zitten voor backwards compatiblity. Het was altijd wel uit te zetten door de MS extensions in z'n geheel uit te zetten, maar dan compileert natuurlijk niets meer omdat de windows headers e.d. van die extensies gebruik maken.

Een andere manier om er omheen te werken was om dit van tevoren te definieren:
C++:
1
#define for     if (0) { } else for


In de nieuwe MSVC++ (vanaf 7.0 aka 2002) is het wel met een simpele compile optie uit te zetten, en krijg je ook een warning als je van de extensie gebruik maakt

(
waar overigens nog een nasty bug in zit kwam ik laatst achter

Ik had zoiets in mijn code:
C++:
1
2
3
4
5
6
7
8
9
10
11
for (int i = 0; i < num; i++)
{
    // ...
}

int i = 0;
while (...)
{
    // ...
    i++;
}


Hier kreeg ik dus ten onrechte de warning dat ik van de extensie gebruik maakte, en het compileerde vervoglens nog verkeerd ook, omdat de assignment i = 0 gewoonweg niet uitgevoerd werd, en het in de while lus dus totaal niet klopte :(
MSVC++ 7.1 (2003) was dat
)

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.


Verwijderd

Topicstarter
Dan voor de laatste keer (denk ik) nog een aantal aanpassingen:


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
#include <iostream>
#include <iomanip>
using namespace std;

#define MAX 50

int main()
{
    int getallen[MAX];
    int invoer;
    int AANTAL = 0;
    
    while ( invoer != 0 )
    {
        cout << "geef een getal: ";
        cin >> invoer;
        getallen[AANTAL] = invoer;
        AANTAL++;

    }

    for ( int i = 0; i <= AANTAL ; i++ )
    {
        cout << setw(5) << getallen[i] << "\n";
    }
}

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

'invoer' heeft nog steeds een ongedefinieerde waarde aan het begin van je while lus

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.


Verwijderd

Als AANTAL = 1 dan krijg je nog steeds twee regels output....
Pagina: 1