[C] comparison between pointer and integer

Pagina: 1
Acties:

  • Ethnocentrix
  • Registratie: Augustus 2002
  • Laatst online: 20:57

Ethnocentrix

Rijkserkend prutser

Topicstarter
Ik ben bezig C te leren, maar ik zit nu toch wel behoorlijk vast.
Als oefening heb ik dit programma'tje geschreven:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

main()
{
    char ltr, *pnt;
    pnt = &ltr;
    
    pnt = 0;
    printf("Voer een zin in, en sluit met een punt (.):\n");
    while (*pnt = getchar() || *pnt != "\n")
    {
        pnt++;
    }
    
    for (pnt;pnt > 0;pnt--)
    {
        putchar(*pnt);
    }
}

De bedoeling is dat er een zin ingelezen wordt, en dat die zin vervolgens omgedraaid op het scherm wordt neergezet. Het probleem is alleen dat ik bij het compilen deze fout krijg:
code:
1
2
draaiom.c: In function `main':
draaiom.c:10: warning: comparison between pointer and integer


Omdat er stond dat de pointer vergeleken werd met een integer (terwijl ik een char aanmaak :?) heb ik "\n" vervangen voor een getal. Dan compiled het programma wel, maar dan werkt het programma natuurlijk niet.

Weet iemand wat er verkeerd is aan dit programma? Het zal ongetwijfeld een stomme fout zijn, maar ik kan 'm echt niet vinden.

[ Voor 5% gewijzigd door Ethnocentrix op 13-03-2005 20:35 . Reden: typo's ]

You know you're an engineer if you have no life & can prove it mathematically.


  • Sihaya
  • Registratie: Juni 2001
  • Niet online

Sihaya

Pasfoto:

Het probleem is dat je *pnt != "\n" hebt staan, die laatste "\n" wordt door de compiler in een string-array omgezet. Als je hier '\n' van maakt wordt dit wel als een char herkend.

signature has expired


Verwijderd

Hier geeft je programma trouwens een segmentation fault...

  • Ethnocentrix
  • Registratie: Augustus 2002
  • Laatst online: 20:57

Ethnocentrix

Rijkserkend prutser

Topicstarter
Ik ben wat verder. Blijkbaar mag dit niet: "\n", maar dit wel '\n' .
Nu compiled het programma wel, maar krijg ik een segmentation fault zodra ik op enter druk.

edit: ik ben te langzaam 8)7.

[ Voor 17% gewijzigd door Ethnocentrix op 13-03-2005 21:01 ]

You know you're an engineer if you have no life & can prove it mathematically.


Verwijderd

In regel 6 laat je de pointer pnt verwijzen naar de variabele ltr. Dat is goed.

In regel 8 laat je de pointer pnt verwijzen naar het geheugenadres 0. Dat is vrijwel zeker (lees: zeker) een adres waar je niet mag lezen of schrijven, dus dat is fout.

In de voorwaarde van de while-loop in regel 10, in "*pnt != "\n", doe je twee dingen fout:

je vergelijkt twee strings (type char * of char[]) met elkaar met een !=. Dat kan niet: == en != vergelijken bij pointers (en pnt is een pointer) de geheugenadressen, en niet de inhoud daarvan. pnt verwijst niet naar waar "\n" in het geheugen staat.

daarbij schrijf je *pnt in plaats van pnt. Je wilt de laatste opschrijven. Dat komt omdat als je char *pnt definieert, je vervolgens pnt van type char* en *pnt van type char hebt: pnt verwijst naar het geheugenadres van de pointer, *pnt naar het karakter (dus niet: de string) die daar te vinden is.

Afijn, ik kan het je hier niet allemaal uitleggen. Zoek een goed verhaal over C en lees dat eens goed door.

Edit:
Mijn verhaal over == en != en *pnt in plaats van pnt mag je vergeten, ik interpreteerde je code daar verkeerd.

De segmentation fault komt door de pnt = 0, waar je pnt laat verwijzen naar een geheugenadres waar je niet mag lezen of schrijven. Je moet zorgen dat het naar een adres gaat verwijzen waar naar geschreven en van gelezen mag worden.

[ Voor 17% gewijzigd door Verwijderd op 13-03-2005 21:04 ]


  • Ethnocentrix
  • Registratie: Augustus 2002
  • Laatst online: 20:57

Ethnocentrix

Rijkserkend prutser

Topicstarter
Iedereen bedankt voor de reacties!

ik heb het programma nu zo:
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
#include <stdio.h>
#include <stdlib.h>

main()
{
    /* initialiseer de variabelen */
    char ltr, *pnt;
    int teller = 1;
    
    /* geef aan dat pnt verwijst naar de inhoud van ltr */
    pnt = &ltr;
    
    printf("Voer een zin in, en sluit met een punt (.):\n");
    
    /* Vraag om een letter. sla deze op in een char mbv. een pointer, en tel bij het geheugenadres 1 op */
    /* Herhaal dit totdat er op enter wordt gedrukt                             */
    while ((*pnt = getchar()) != '\n')
    {
        pnt++;
        teller++;
    }
    
    /* Haal net zo vaak 1 van de teller en het geheugenadres af tot de teller op 0 staat    */
    /* Lees elke keer het geheugenadres uit, en zet de inhoud op het scherm         */
    for (teller;teller > 0;teller--)
    {
        putchar(*pnt);
        pnt--;
    }
    
    /* geef een extyra enter zodat de command prompt niet gesloopt wordt.           */
    printf("\n");
}


Het werkt nu perfect!
Nogmaals bedankt!

You know you're an engineer if you have no life & can prove it mathematically.


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Ethnocentrix schreef op zondag 13 maart 2005 @ 21:22:
Het werkt nu perfect!
Nogmaals bedankt!
Het is idd mogelijk dat het programma werkt (lees: niet crashed), maar je doet toch nog iets verkeerd, waardoor het net zo goed wel zou kunnen crashen.

Je wilt een zin inlezen, maar je hebt maar ruimte voor 1 char aangevraagd (de "ltr"). Het eerste teken dat je inleest komt in "ltr" te staan, en dat is goed. Maar voor elk volgende teken wordt het ergens in een stuk geheugen gezet wat je eigenlijk niet gereserveerd hebt.

De oplossing is om wel voldoende ruimte voor een zin te reserveren door niet 1, maar een hele array van chars te alloceren. Probeer het eens zo:
C:
1
2
3
4
5
6
7
8
/* initialiseer de variabelen */

char zin[80]; //Een array van 80 karakters
char *pnt;
int teller = 1;
    
/* geef aan dat pnt verwijst naar het begin van zin  */
pnt = zin;

De laatste regel is hetzelfde als "pnt = &zin[0]", m.a.w. "het adres van het eerste element van zin".

  • Ethnocentrix
  • Registratie: Augustus 2002
  • Laatst online: 20:57

Ethnocentrix

Rijkserkend prutser

Topicstarter
Als ik een lange zin invoer krijg ik inderdaad een segmentation fault.
Ik dacht (hoopte :P) dat zodra ik het geheugenadres met 1 verhoogde, C automatisch dat plekje ook als char zou reserveren, maar dat gebeurt dus blijkbaar niet.
Ik heb de code die je gaf in het programma gestopt, en nu kan ik inderdaad wel lange zinnen invoeren. Het enige nadeeltje is daj je maximaal 81 karakters kan invoeren, maar veel meer is toch niet nodig.

Wederom bedankt!

You know you're an engineer if you have no life & can prove it mathematically.


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Ethnocentrix schreef op maandag 14 maart 2005 @ 00:16:
Als ik een lange zin invoer krijg ik inderdaad een segmentation fault.
Ik dacht (hoopte :P) dat zodra ik het geheugenadres met 1 verhoogde, C automatisch dat plekje ook als char zou reserveren, maar dat gebeurt dus blijkbaar niet.
Ik heb de code die je gaf in het programma gestopt, en nu kan ik inderdaad wel lange zinnen invoeren. Het enige nadeeltje is daj je maximaal 81 karakters kan invoeren, maar veel meer is toch niet nodig.

Wederom bedankt!
Zoek eens op wat de functies malloc, calloc en realloc doen. ;) Ook niet vergeten om de functie free te gebruiken. Op die manier kun je dynamische arrays maken, die steeds, wanneer nodig, een element groter worden. Door free te gebruiken aan het eind van je programma, ruim je je geheugen weer op, zodat je ook geen memory leaks krijgt. :)
Zie ook http://www.die.net/doc/linux/man/man3/realloc.3.html of een vergelijkbare pagina.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.

Pagina: 1