Avatar billede stringbuffer Nybegynder
29. januar 2003 - 21:03 Der er 15 kommentarer og
2 løsninger

ftell/fread på Win32

Jeg har lavet følgende simple program, der virker fint under linux. Såvidt jeg har kunnet læse i diverse hjælpefiler, burde det også virke under win32, hvor man bruger io.h istedet for unistd.h. Men det gør det ikke.

hvad er der galt?

Her er koden:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <io.h>

void fail(const char *s)
{
        perror(s);
        getchar();
        exit(1);
}

int main(void)
{
        FILE *fp;
        int len;
        char *content;
        fp = fopen("index.tpl", "r");
        if (fp == NULL)
                fail("fopen");
        fseek(fp, 0, SEEK_END);
        len = ftell(fp);
        rewind(fp);
        content = new char[len+1];
        if (fread(content, len, 1, fp) < 0)
                fail("fread");
        puts(content);
        delete [] content;
        getchar();
        return 0;
}
Avatar billede stringbuffer Nybegynder
29. januar 2003 - 21:06 #1
hovsa, det er forkert version... den, jeg ikke kan få til at virke har:
        if (fread(content, len, 1, fp) < 1)
                fail("fread");
Avatar billede soreno Praktikant
29. januar 2003 - 21:07 #2
Dette fungere fint med min compiler (MinGW):

//get file size
FILE *file;
file = fopen("foo.bar", "rb");
if(file)
{
  fseek(file, 0, SEEK_END);
  int fileSize = ftell(file);
  fseek(file, 0, SEEK_SET);
  printf("size %i\n", fileSize);
}


Hvilken compiler bruger du ?
Hvad er der i "io.h" som ikke er i "stdio.h" ?
Avatar billede stringbuffer Nybegynder
29. januar 2003 - 21:07 #3
Hvis jeg erstatter len med len-122 så virker det.... underligt nok!?!?!? (og hele filens indhold bliver læst)

        if (fread(content, len-122, 1, fp) < 0)
                fail("fread");
Avatar billede stringbuffer Nybegynder
29. januar 2003 - 21:08 #4
Forklaring udbedes på ovenstående
Avatar billede soreno Praktikant
29. januar 2003 - 21:14 #5
Kan du ikke prøve at forklare hvad det er koden gerne skulle gøre ?
Skal den læse indholdet af "index.tpl" til en buffer og printe bufferen til stdout ?
Avatar billede soreno Praktikant
29. januar 2003 - 21:23 #6
Prøv:
if (fread(content, 1, len, fp) < 0)
                fail("fread");

Se:
http://www.cplusplus.com/ref/cstdio/fread.html
Avatar billede arne_v Ekspert
29. januar 2003 - 21:36 #7
io.h indeholder groft sagt alt Unix I/O som ikke kom med i ANSI C.
Avatar billede stringbuffer Nybegynder
29. januar 2003 - 21:38 #8
den skal egentlig bare læse den til bufferen, det er lidt misvisende at jeg har den dér puts med...
Avatar billede stringbuffer Nybegynder
29. januar 2003 - 21:40 #9
fejlen melder sig ved at jeg får besked fra fail("fread");
Avatar billede arne_v Ekspert
29. januar 2003 - 21:42 #10
Og som er i unistd.h på posix compliant platforme.
Avatar billede stringbuffer Nybegynder
29. januar 2003 - 21:44 #11
Nu har jeg prøvet held med at bruge read istedet:

int main(void)
{
        int fd;
        int len;
        char *content;
        if ((fd = open("index.tpl", O_RDONLY)) == -1)
                fail("open");
        len = lseek(fd, 0, SEEK_END);
        lseek(fd, 0, SEEK_SET);
        content = new char[len+1];
        printf("Len is: %d\n", len);
        if ((len = read(fd, content, len)) < 1)
                fail("read");
        printf("Read %d bytes\n", len);
        getchar();
        content[len] = 0;
        puts(content);
        delete [] content;
        getchar();
        return 0;
}

Jeg får flg. resultat på skærmen:
Len is: 5345
Read 5223 bytes
Hvorefter den udskriver HELE indholdet af filen, der mangler ikke noget...

Så det store spørgsmål går i virkeligheden ud på hvorfor seek til slutningen af filen tilsyneladende giver en position, der er 122 bytes for meget i forhold til længden!?!?
Avatar billede arne_v Ekspert
29. januar 2003 - 21:49 #12
Gæt: der er 122 linier i filen !
Avatar billede arne_v Ekspert
29. januar 2003 - 21:50 #13
En rigtig DOS/WINDOWS fil har linierne adskilt af CR+LF.

I C læses de op som en char ('\n').

Måske kommer differencen derfra.
Avatar billede arne_v Ekspert
29. januar 2003 - 21:50 #14
Og på Unix er linierne kun adskilt af LF og derfor
er det 1:1 !
Avatar billede soreno Praktikant
29. januar 2003 - 21:51 #15
Prøv at åbne den i binary mode:
fd = fopen("index.tpl", "rb")
Avatar billede arne_v Ekspert
29. januar 2003 - 21:51 #16
Filen er formentlig fysisk 5335 bytes hvis du laver en DIR på den.
Avatar billede stringbuffer Nybegynder
29. januar 2003 - 22:02 #17
den er 5.345 når jeg laver dir... men jeg er sikker på at I har ret.
jeg prøvede at lave en binary read og så passede pengene :)
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