Avatar billede spectual Nybegynder
05. juli 2001 - 21:39 Der er 14 kommentarer og
1 løsning

feof spørgsmål

Kan nogen gennemskue (runtime) fejlen i følgende kode:

void LoadStudents () {

    student *newstudent;

    FILE *myfile;

    myfile = fopen (\"c:\\\\students.dat\", \"rb\");

    if (myfile == NULL) { return; } // filen kunne ikke åbnes

    while (feof (myfile) == false) {

        newstudent = allocatestudent();

        if (current == NULL) { current = newstudent; headptr = newstudent; } // første student overhovedet

        current->next = newstudent;
        current = current->next;

        fread (newstudent, sizeof (struct student), 1, myfile);

        printf (\"hentede : %s\\n\",newstudent->name);
       
    }

    fclose (myfile);
}

Student er en class, som er 24 bytes stor.
Filen c:\\students.dat er 48 bytes stor.

Men alligevel henter funktionen 3 studenter?

porquè?
Avatar billede stringbuffer Nybegynder
05. juli 2001 - 22:00 #1
Hvad er current? Hvor kommer den fra? Er det en hægtet liste, du har som en eller anden global variabel? (fy fy!)
Hvor bliver de allokerede variable slettet?
Avatar billede stringbuffer Nybegynder
05. juli 2001 - 22:14 #2
Hvorfor kan du ikke bare nøjes med flg:

void LoadStudents ()
{
    FILE *myfile;
    if ((myfile = fopen (\"c:\\\\students.dat\", \"rb\")) == NULL)
        return; // filen kunne ikke åbnes
    while (feof (myfile) == false)
    {
            current->next = allocatestudent();
            current = current->next;
            fread (current, sizeof (struct student), 1, myfile);
            printf (\"hentede : %s\\n\",current->name);
       
    }
    current->next = NULL;
    fclose (myfile);
}
Avatar billede spectual Nybegynder
05. juli 2001 - 22:15 #3
Problemet er, at feof først bliver true, når der er forsøg at læse over EOF.

Funktionen skal konstrueres sådan, at en student bliver læst ind i et midlertidigt buffer hvorefter det kopieres over i den ny-allokerede variabel.

current styrer en hægtet liste (dvs. den peger på sidste element i en hægtet liste).

Variablerne bliver ikke slettet.
Avatar billede spectual Nybegynder
05. juli 2001 - 22:20 #4
Dit forslag får programmet til at crashe.
Avatar billede stringbuffer Nybegynder
05. juli 2001 - 22:29 #5
hvad med

void LoadStudents ()
{
        FILE *myfile;
        if ((myfile = fopen (\"c:\\\\students.dat\", \"rb\")) == NULL)
            return; // filen kunne ikke åbnes
    do
    {
        current->next = allocatestudent();
        current = current->next;
    }
        while (fread(current, sizeof (struct student), 1, myfile) != 0));
    delete current;
        current = NULL;
        fclose (myfile);
}

?
Avatar billede stringbuffer Nybegynder
05. juli 2001 - 22:30 #6
sorry, jeg har ikke din klasse og tester ikke mine forslag...
Avatar billede stringbuffer Nybegynder
05. juli 2001 - 22:31 #7
Jeg går ud fra at du bare vil indlæse i slutningen af listen og afslutte listen med NULL. Tager jeg fejl?
Avatar billede spectual Nybegynder
05. juli 2001 - 22:32 #8
Det er korrekt.

Følgende virker efter hensigten - det skal bare optimeres:

void LoadStudents () {

    student *newstudent;

    FILE *myfile;

    int res;

    myfile = fopen (\"c:\\\\students.dat\", \"rb\");

    if (myfile == NULL) { return; } // filen kunne ikke åbnes

    bool mtr = true;

    while (mtr == true) {

        newstudent = allocatestudent();

        if (current == NULL) { current = newstudent; headptr = newstudent; } // første student overhovedet

        res = fread (newstudent, sizeof (struct student), 1, myfile);

        if (res != NULL) {

            current->next = newstudent;
               
            current = current->next;
       
            printf (\"hentede : %s\\n\",newstudent->name);

        } else {
            current->next = NULL;
            printf (\"got it\\n\");
            free (newstudent); // fordi hukommelsen allerede er allokeret
        }


        if (feof (myfile)) { mtr = false; }

    }

    fclose (myfile);
}
Avatar billede stringbuffer Nybegynder
05. juli 2001 - 23:41 #9
Det burde være nok med det her:

void LoadStudents ()
{
    FILE *myfile;
    if ((myfile = fopen (\"c:\\\\students.dat\", \"rb\")) == NULL)
            return; // filen kunne ikke åbnes
    do
    {
        current->next = allocatestudent();
        current = current->next;
    }
    while (fread(current, sizeof (struct student), 1, myfile) != 0);
    free (current);
    current = NULL;
    fclose (myfile);
}

Jeg troede først at det var C++, men kan nu se at det er god gammeldags C - så du bruger sfølli malloc og free...

...jeg vil dog råde dig til at lave funktionen så den tager slutningen af listen (din current) som en referenceparameter, globale variable er noget snavs fordi det nemt kan blive svært at overskue hvilke funktioner kan ændre på dem.

Avatar billede stringbuffer Nybegynder
05. juli 2001 - 23:42 #10
hov, det er jo C++
ellers ville du jo ikke kunne bruge // kommentarer
men kun /* c-style kommentarer */

Hvorfor bruger du så ikke new og delete???
Avatar billede stringbuffer Nybegynder
05. juli 2001 - 23:46 #11
Fatter minus af det her... hvorfor er funktionen ikke lavet som en medlemsfunktion i klassen student (og tager en FILE* paramater) eller som en fri funktion, der returnerer en hægtet liste med student-objekter?
Avatar billede spectual Nybegynder
06. juli 2001 - 01:08 #12
Jeg er newbee i C++ , derfor :)
Avatar billede stringbuffer Nybegynder
06. juli 2001 - 01:36 #13
ok...
Avatar billede stringbuffer Nybegynder
06. juli 2001 - 01:49 #14
Hvad med det her?

Denne kan f.eks. kaldes med current som argument

void LoadStudents (student &*pSidste)
{
    FILE *myfile;
    student stud;
    if ((myfile = fopen(\"c:\\\\students.dat\", \"rb\")) == NULL)
            return; // filen kunne ikke åbnes
    while (fread(&stud, sizeof(student), 1, myfile) != 0)
    {
        pSidste = new student(stud);
        pSidste = pSidste->next;
    }
    pSidste = NULL;
    fclose (myfile);
}

dette forudsætter at du enten har en copy-constructor til student, men det har du jo selføllig automatisk hvis du er ligeglad med om pointer-variable bliver kopieret med.
Avatar billede stringbuffer Nybegynder
06. juli 2001 - 01:52 #15
...eller at dit objekt kan kopieres ved bytevis kopiering (og det kan det vist siden du kan indlæse det fra fil med fread)
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