Toon posts:

[c] Inhoud pointer wegschrijven naar bestand

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi

Wij zijn op dit moment met onze school opdracht bezig, hierbij moeten we een pointer naar een text file wegschrijven. Dit wil niet lukken.
We weten dat we niet het adres moeten wegschrijven (dus niet %p meegeven) maar we weten niet hoe wel het wel moeten doen.
code:
1
2
3
4
5
6
7
8
9
toevoeg = fopen (leesinhoud, "w");

while (begingegevens -> next != NULL)
{
     fprintf (toevoeg, "%s\n", begingegevens -> kolomnaam);
     fprintf (toevoeg, "%d\n", begingegevens -> intwaarde);
     fprintf (toevoeg, "%s\n", begingegevens -> strwaarde);
     begingegevens = begingegevens -> next;
}

kolomnaam is een string, intwaarde is een integer en strwaarde is een pointer naar een string.
Het wegschrijven van str waarde geeft een segmentation fault.
Hoe kunnen we hem wegschrijven ?

ps, onze docent was gisteren niet aanwezig en vandaag is hij er ook niet (en het moet vrijdag af :()

  • cobratbq
  • Registratie: Maart 2001
  • Laatst online: 17-12-2015
Ik dacht zelf dat je een pointer weg moest schrijven alsof he gewoon een string was.
Dus gewoon:
code:
1
printf("bestand","%s", pointer);

(Of iets dergelijks :) )

edit:
Is de pointer ook gedeclareerd als charpointer?
dus:
[code]char *pointer;[/code]

One ring to rule them all, one ring to find them, one ring to bring them all, and in darkness bind them...


Verwijderd

Topicstarter
thx voor de snelle reactie, we gaan het ff proberen

en ja, hij is gedefinieerd zoals je vermeld

  • cobratbq
  • Registratie: Maart 2001
  • Laatst online: 17-12-2015
Graag gedaan *D

One ring to rule them all, one ring to find them, one ring to bring them all, and in darkness bind them...


Verwijderd

Op woensdag 03 juli 2002 11:47 schreef cobratbq het volgende:
Graag gedaan *D
At your service ???

  • Habbie
  • Registratie: Juni 2002
  • Laatst online: 27-08 14:36
Op woensdag 03 juli 2002 11:37 schreef nantasquad het volgende:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
toevoeg = fopen (leesinhoud, "w");



while (begingegevens -> next != NULL)

{

     fprintf (toevoeg, "%s\n", begingegevens -> kolomnaam);

     fprintf (toevoeg, "%d\n", begingegevens -> intwaarde);

     fprintf (toevoeg, "%s\n", begingegevens -> strwaarde);

     begingegevens = begingegevens -> next;

}



kolomnaam is een string, intwaarde is een integer en strwaarde is een pointer naar een string.

Het wegschrijven van str waarde geeft een segmentation fault.

Hoe kunnen we hem wegschrijven ?



ps, onze docent was gisteren niet aanwezig en vandaag is hij er ook niet (en het moet vrijdag af :()
Laat es zien hoe je variabelen gedefinieerd zijn en hoe je er data in hebt gezet? strwaarde is duidelijk niet kosher.

-- Peter van Dijk


Verwijderd

Topicstarter
Dit is onze header file
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
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAXSTRING 100

typedef struct metatype
     {
         char kolomnaam[MAXSTRING];
         int kolomtype;
         int stringlengte;
         struct metatype *next;
     } Metatype;

typedef struct  inhoudtype
     {
         char kolomnaam[MAXSTRING];
         int intwaarde;
         char *strwaarde;
         struct inhoudtype *next;
     } Inhoudtype;

typedef struct tabeltype
     {
         struct inhoudtype *waarde;
         struct tabeltype *next;
     } Tabeltype;

int aanmakenTabel (char *databasenaam[MAXSTRING]);
int verwijderenTabel (char *databasenaam[MAXSTRING]);

int verwijderenDatabase ();

int verwijderenGegevens (char *databasenaam[MAXSTRING]);
int invoegenGegevens (char *databasenaam[MAXSTRING]);
int wijzigenGegevens (char *databasenaam[MAXSTRING]);
int selecteerGegevens (char *databasenaam[MAXSTRING]);

int leegLijst (Inhoudtype *waarde);

Op deze manier vullen we de liniare lijst.
code:
1
2
        printf ("\nGeef de waarde van [%s]\n", metagegevens -> kolomnaam);
        sprintf (huidigegegevens -> kolomnaam, "%s", metagegevens -> kolomnaam);

Dit is het inlezen van de kolomnaam, deze is hetzelfde als de kolomnaam in onze meta gegevens.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (metagegevens -> kolomtype == 2) // is integer
         {
             fflush (stdin);
             printf ("Insert | -->");
             scanf ("%d", &huidigegegevens -> intwaarde);
             huidigegegevens -> strwaarde = NULL;
         }

         else // is string
         {
             fflush (stdin);
             printf ("Insert | -->");
             huidigegegevens -> strwaarde = malloc(sizeof(metagegevens -> stringlengte));
             scanf ("%s", huidigegegevens -> strwaarde);
         }
        }

hier lezen we de waarde in, de waarde kan van het type string (met lengste metagegevens -> stringlengte) of integer zijn. Dit type staat opgeslagen in de metagegevens (kolomtype, 1 is string, 2 is integer)

Als er nog meer bij moet, moet je het ff melden.

en de oplossing van cobratbq werkt niet, krijgen we compile errors op, en we willen naar een file wegschrijven dus fprintf (bestand, type, waarde)

  • Dash2in1
  • Registratie: November 2001
  • Laatst online: 31-08 22:49
code:
1
huidigegegevens -> strwaarde = malloc(sizeof(metagegevens -> stringlengte));

Dit lijkt me niet echt de bedoeling, je wijst nu die char* naar een stukje geheugen ter grootte van het type van metagegevens->stringlengte (int dus ..)

probeer dan zoiets als
code:
1
huidigegegevens->strwaarde = malloc (sizeof(char) * metagegevens->stringlengte);

of
code:
1
huidigegegens->strwaarde = malloc (sizeof(char) *(metagegevens->stringlengte + 1));

met +1 omdat er eventueel in de stringlengte de \0 over het hoofd is gezien..

Verwijderd

Topicstarter
Op woensdag 03 juli 2002 12:20 schreef Dash2in1 het volgende:
code:
1
huidigegegevens -> strwaarde = malloc(sizeof(metagegevens -> stringlengte));

Dit lijkt me niet echt de bedoeling, je wijst nu die char* naar een stukje geheugen ter grootte van het type van metagegevens->stringlengte (int dus ..)

probeer dan zoiets als
code:
1
huidigegegevens->strwaarde = malloc (sizeof(char) * metagegevens->stringlengte);

of
code:
1
huidigegegens->strwaarde = malloc (sizeof(char) *(metagegevens->stringlengte + 1));

met +1 omdat er eventueel in de stringlengte de \0 over het hoofd is gezien..
hmm, klopt. We zijn alleen nog niet zover dat we kunnen wegschrijven maar dit is alvast een (grote) fout minder.

  • Dash2in1
  • Registratie: November 2001
  • Laatst online: 31-08 22:49
code:
1
fprintf (toevoeg, "%s\n", begingegevens -> strwaarde);

Daar krijg je nogsteeds die segmentation fault op??
Probeer eens te kijken of die uberhaupt wel gevuld is:
code:
1
fprintf(stderr,"%s\n",begingegevens->strwaarde);

Ben benieuwd of hij al bij de 1e fout gaat ..

(Overigens denk ik niet dat je genoeg info geeft om echt nu nog wat te kunnen zeggen over wat er mis gaat ... hoe wordt iets van huidige gegevens in begingegevens gezet bijvoorbeeld?!)

Verwijderd

Topicstarter
Op woensdag 03 juli 2002 12:58 schreef Dash2in1 het volgende:
code:
1
fprintf (toevoeg, "%s\n", begingegevens -> strwaarde);

Daar krijg je nogsteeds die segmentation fault op??
Probeer eens te kijken of die uberhaupt wel gevuld is:
code:
1
fprintf(stderr,"%s\n",begingegevens->strwaarde);

Ben benieuwd of hij al bij de 1e fout gaat ..

(Overigens denk ik niet dat je genoeg info geeft om echt nu nog wat te kunnen zeggen over wat er mis gaat ... hoe wordt iets van huidige gegevens in begingegevens gezet bijvoorbeeld?!)
ondertussen hebben we daar geen segmentation fault op (weten nog niet of hij dat statement doet)

maar toch bedankt, we gaan nu weer ff druk verder, jullie horen het wel weer.

Verwijderd

Topicstarter
he

we hebben het ondertussen zelf opgelost, de fout zat niet in het wegschrijven naar het bestand, dat deed hij later dus wel goed.
De fout zat in het declareren van het geheugen voor strwaarde.
code:
1
gegevens -> strwaarde = malloc(sizeof(char[metagegevens -> stringlengte]));

dat moet het zijn.
strwaarde is een pointer naar het type char, en met dit statement regelen we de juiste hoeveelheid geheugen voor hem.
Je reserveerd nu geheugen voor een string van maximaal stringlengte aantal characters. Wij hadden eerst iets anders en de mogelijke oplossing die door jullie gegeven werd werkte ook niet (toch bedankt daarvoor, was een stap in de goed richting).

thx iedereen

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 12:21
Wedden dat als je deze code volgende maand terugziet, je niet meer weet of stringlengte inclusief of exclusief het 0-karakter was? Je doet er dus goed aan dit (en eigenlijk alle andere invarianten) te documenteren in je broncode.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 05 juli 2002 08:51 schreef nantasquad het volgende:
code:
1
gegevens -> strwaarde = malloc(sizeof(char[metagegevens -> stringlengte]));

dat moet het zijn.
Hmm.
sizeof(char[metagegevens -> stringlengte]) is wel een ingewikkelde manier om metagegevens -> stringlengte te schrijven.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 12:47

johnwoo

3S-GTE

Nog iets...
code:
1
2
3
4
5
6
7
while (begingegevens -> next != NULL)
{
     fprintf (toevoeg, "%s\n", begingegevens -> kolomnaam);
     fprintf (toevoeg, "%d\n", begingegevens -> intwaarde);
     fprintf (toevoeg, "%s\n", begingegevens -> strwaarde);
     begingegevens = begingegevens -> next;
}

Hiermee sla je altijd het laatste element van je linked list (wat dus NULL heeft als next pointer) over, aangezien deze pointer bij het laatste geldige element NULL is.
En, erger, als je lijst leeg is (en begingegevens dus NULL is) krijg je een memory fault, omdat je een member van begingegevens probeert te bereiken terwijl deze NULL is. Met een kleine wijziging neem je ook het laatste element mee en voorkom je deze memoryfault:
code:
1
2
3
4
5
6
7
Inhoudtype *huidig = begingegevens;
while (huidig) {
    fprintf (toevoeg, "%s\n", huidig->kolomnaam);
    fprintf (toevoeg, "%d\n", huidig->intwaarde);
    fprintf (toevoeg, "%s\n", huidig->strwaarde);
    huidig = huidig->next;
}

Overigens klopt de semantiek niet echt als je gaat iteraten met een pointer die 'begingegevens' heet :) Na de eerste iteratie zal deze namelijk niet meer naar het begin van de lijst wijzen :)

Al moet ik bekennen dat ik me ook wel eens schuldig maak aan het 'hergebruik' van variabelen om n paar bytes te besparen :o

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


Verwijderd

Topicstarter
Soultaker schreef op 05 juli 2002 @ 12:15:
Wedden dat als je deze code volgende maand terugziet, je niet meer weet of stringlengte inclusief of exclusief het 0-karakter was? Je doet er dus goed aan dit (en eigenlijk alle andere invarianten) te documenteren in je broncode.
het is ook niet meer nodig om hem terug te kijken, opdracht is voltooid en cijfer is binnen.
johnwoo schreef op 06 juli 2002 @ 01:40:
Nog iets...
code:
1
2
3
4
5
6
7
while (begingegevens -&gt; next != NULL)
{
     fprintf (toevoeg, &quot;%s\n&quot;, begingegevens -&gt; kolomnaam);
     fprintf (toevoeg, &quot;%d\n&quot;, begingegevens -&gt; intwaarde);
     fprintf (toevoeg, &quot;%s\n&quot;, begingegevens -&gt; strwaarde);
     begingegevens = begingegevens -&gt; next;
}

Hiermee sla je altijd het laatste element van je linked list (wat dus NULL heeft als next pointer) over, aangezien deze pointer bij het laatste geldige element NULL is.
En, erger, als je lijst leeg is (en begingegevens dus NULL is) krijg je een memory fault, omdat je een member van begingegevens probeert te bereiken terwijl deze NULL is. Met een kleine wijziging neem je ook het laatste element mee en voorkom je deze memoryfault:
code:
1
2
3
4
5
6
7
Inhoudtype *huidig = begingegevens;
while (huidig) {
    fprintf (toevoeg, &quot;%s\n&quot;, huidig-&gt;kolomnaam);
    fprintf (toevoeg, &quot;%d\n&quot;, huidig-&gt;intwaarde);
    fprintf (toevoeg, &quot;%s\n&quot;, huidig-&gt;strwaarde);
    huidig = huidig-&gt;next;
}

Overigens klopt de semantiek niet echt als je gaat iteraten met een pointer die 'begingegevens' heet :) Na de eerste iteratie zal deze namelijk niet meer naar het begin van de lijst wijzen :)

Al moet ik bekennen dat ik me ook wel eens schuldig maak aan het 'hergebruik' van variabelen om n paar bytes te besparen :o
bij de eerste is het geen probleem omdat we die next ook niet zelf inlezen maar runtime een nieuwe waarden geven.

bij de 2e, daar heb je idd een beetje gelijk in (weet niet precies waar die code in het programma staat)

Ondertussen is het al weer een eind verder en is de opdracht voltooid (en werkend)

deze definitie klopt ook niet
code:
1
gegevens -&gt; strwaarde = malloc(sizeof(char[metagegevens -&gt; stringlengte]));


je reserveerd nu een geheugen stuk van de lengte van stringlengte. Je krijgt dus niet stringlengte aantal karacters als geheugen ruimte.

het moet dit zijn
code:
1
gegevens -&gt; strwaarde = malloc(metagegevens -&gt; stringlengte * (sizeof(char));


nu reserveer je geheugen voor stringlengte aantal karacters (zoals moest)

Het programma bevatte trouwens te veel fouten waardoor we het niet af hadden op vrijdag, gelukkig kregen we uitstel tot dinsdag en hebben we het nog gehaald.



ik post dit zodat eventuele andere mensen die dit ooit lezen nog de juiste declaratie van het geheugen gebruiken en dus niet de fout in gaan omdat ik te lui was het juiste antwoord te posten, alleen had ik het wel een stukje eerder moeten doen

  • windancer
  • Registratie: Maart 2000
  • Laatst online: 18-08 22:36
Verwijderd schreef op 31 juli 2002 @ 07:54:

deze definitie klopt ook niet
code:
1
gegevens -&gt; strwaarde = malloc(sizeof(char[metagegevens -&gt; stringlengte]));


je reserveerd nu een geheugen stuk van de lengte van stringlengte. Je krijgt dus niet stringlengte aantal karacters als geheugen ruimte.

het moet dit zijn
code:
1
gegevens -&gt; strwaarde = malloc(metagegevens -&gt; stringlengte * (sizeof(char));


nu reserveer je geheugen voor stringlengte aantal karacters (zoals moest)
Het is beide goed, omdat er uit beide hetzelfde komt.

Kijk maar :

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
[wj@localhost wj]$ cat blah.c
#include &lt;stdio.h&gt;
int main()
{
    printf(&quot;sizeof(char[42])  = %d\n&quot;, sizeof(char[42]));
    printf(&quot;42 * sizeof(char) = %d\n&quot;, 42 * sizeof(char));

    exit (0);
}
[wj@localhost wj]$ gcc -o blah blah.c
[wj@localhost wj]$ ./blah
sizeof(char[42])  = 42
42 * sizeof(char) = 42
Pagina: 1