Avatar billede needs Nybegynder
24. juli 2003 - 23:33 Der er 26 kommentarer og
1 løsning

Vil gemme store Arrays af long long's

Okay... her er en af de svære....  hvordan gemme man hurtist 10.000 long long's (tæt på int_64) i en fil? (Bruger visual .net 2003)
Og så det naturlige følge spørgsmål: hvordan load'er man dem så ind igen? -bruger ">>", "<<" og en løkke lige nu.
Avatar billede bertelbrander Novice
24. juli 2003 - 23:41 #1
Det hurtigste er sansynligvis at bruge fwrite til at gemme og fread til at læse.
Hvis du har dem i et array kan du gemme og læse dem alle i et kald til fread/fwrite.
Hvad mener du med "(tæt på int_64)"?
Avatar billede needs Nybegynder
24. juli 2003 - 23:55 #2
Efter som det ikke er mere end en måned siden jeg fik .net 2003 læste jeg jo lidt i manualerne.... Der står meget tydeligt at long long's og Int_64 ikke altid bliver behandlet ens :-)
Avatar billede needs Nybegynder
24. juli 2003 - 23:59 #3
Hvordan ser filen så enlig ud? - er det ligesom med "<<", med mellemrum mellem hver variabel, eller bliver det binært? - Kan du ikk oz lige skrive 1 hurtigt kode eksempel?
Avatar billede bertelbrander Novice
25. juli 2003 - 00:23 #4
Det bliver en binær fil.

Skrive:
long long array[HUGE];
FILE *f = fopen("whatever.dat", "wb");
fwrite(array, sizeof(long long), HUGE, f);
fclose(f);

Læse:
FILE *f = fopen("whatever.dat", "rb");
fread(array, sizeof(long long), HUGE, f);
fclose(f);
Avatar billede arne_v Ekspert
25. juli 2003 - 07:44 #5
Helt enig med Bertel.

Det er *meget meget* hurtigere at skrive og læse binære tal en at skulle
have dem skrevet og læst som tekst.

(og jeg ville også bruge gode gamle fwrite/fread til det)
Avatar billede segmose Nybegynder
25. juli 2003 - 09:18 #6
Evt. kan du tilføje
setvbuf(f, NULL, _IOFBF, useVBuf);
efter fopen, useVBuf skal have en passende høj værdi, mindst allokerings enhed på harddisken, fx. 32768.
Avatar billede needs Nybegynder
25. juli 2003 - 13:21 #7
segmose >> til hvad nytte? skulle det gøre det hurtigere at gemme det? Skal gemme rigtig mange gange... det er et system hvor data'erne først bliver regnet ud i 10.000 array klumper og der efter så skal samles i én file.
Avatar billede needs Nybegynder
26. juli 2003 - 03:37 #8
bertelbrander >> smid så lige et svar på så jeg kan give dig point- Okay?
Avatar billede bertelbrander Novice
26. juli 2003 - 13:59 #9
Jeg tror ikke det hjælper at bruge setvbuf.
Avatar billede segmose Nybegynder
27. juli 2003 - 01:08 #10
Det kommer fuldstændigt an på det underlæggende OS og hardware, i nogle tilfælde giver det en betragtelig forbedring.
Avatar billede needs Nybegynder
27. juli 2003 - 02:11 #11
bertelbrander >> Okay sad lige og prøvede det.... og se så hvad .net debuggeren sagde om denne linie:

FILE *fprime("cache.pcf", "wb");

Debugger: "error C2078: too many initializers" &
"error C2440: 'initializing' : cannot convert from 'const char [3]' to 'FILE *'"

hvad gør jeg galt? (Har #include <cstdlib>)
Avatar billede needs Nybegynder
27. juli 2003 - 02:13 #12
Agrhh... så det lige da jeg trykkede udfør: Mangler 'fopen' foran '(' !!!
Lidt newbie har man vel også lov til at være :-)
Avatar billede needs Nybegynder
27. juli 2003 - 02:19 #13
Nå så tro man lige det vil virke men næ nej.... se her:

fread(baseprimes, sizeof(long long), BASE, fbaseprimes);

Giver : "error C2059: syntax error : ')'" + to mere med et manglende '+' og ')'.
Det den ikke tåle mellemrummet i "long long"? - Nej vel?
Avatar billede arne_v Ekspert
27. juli 2003 - 09:40 #14
Umiddelbar set den linie OK ud.

Kan du poste linierne ovenover ?
Avatar billede needs Nybegynder
27. juli 2003 - 23:14 #15
cout << endl << "Loading baseprimes..." << endl;
if (fbaseprimes)
{
    fread(baseprimes, sizeof(long long), BASE, fbaseprimes);
    count+= BASE;
}
Avatar billede needs Nybegynder
27. juli 2003 - 23:27 #16
der kom også denne med så jeg lige:
error C2661: 'fread' : no overloaded function takes 3 arguments
/Z_B
Avatar billede bertelbrander Novice
28. juli 2003 - 00:08 #17
Hvordan er baseprimes, BASE og fbaseprimes erklæret?
Jeg kan ikke se at fread kun får 3 argumenter, medmindre du har en underlig erklæring af en af ovennævnte.
Avatar billede arne_v Ekspert
28. juli 2003 - 07:09 #18
Har du inkluderet stdio.h (eller cstdio) ?
Avatar billede needs Nybegynder
29. juli 2003 - 20:06 #19
#define BASE 1000000
long long baseprimes[BASE];
FILE *fbaseprimes("file navn", "rb");
Avatar billede arne_v Ekspert
29. juli 2003 - 20:13 #20
Det går vist ikke.

FILE er en C ting ikke en C++ ting.

#define BASE 1000000
long long baseprimes[BASE];
FILE *fbaseprimes = fopen("file navn", "rb");
Avatar billede arne_v Ekspert
18. august 2003 - 23:52 #21
needs>

Er du kommet videre ?
Avatar billede needs Nybegynder
14. november 2003 - 22:22 #22
bertelbrander >> ved du noget om hvorfor der er en grænse på et sted mellem 100001 og 200K for hvor mange variabler man kan skrive til HD'en i ét array?
Avatar billede bertelbrander Novice
14. november 2003 - 22:39 #23
Det er vel kun naturligt at der er en øvre grænse, jeg har endnu ikke set en komputer med uendelig meget HD/RAM ;-)

Grænsen er afhængig af kompiler og platform, jeg vil tro at standarden garanterer enten 32k eller 64k.

Jeg vil dog forvente at moderne kompilere kan håndtere langt over 100 MBytes.

Så fejlen kan også ligge et andet sted.

Hvilken kompiler/platform bruger du?
Avatar billede needs Nybegynder
14. november 2003 - 22:43 #24
bruger .net 2003 (windows xp home, på en centrino 1.4 med 512MB RAM). Det skulle da ikk ha' noget med com'en at gøre...?
Avatar billede bertelbrander Novice
14. november 2003 - 23:11 #25
Jeg lavede lige et testprogram:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE 32*1024*1024 /* 32MByte */

char Ar1[SIZE];
char Ar2[SIZE];

int main(void)
{
  int i;
  FILE *f;
  for(i = 0; i < SIZE; i++)
    Ar1[i] = rand();

  f = fopen("text.dat", "wb");
  printf("Writing\n");
  if(fwrite(Ar1, 1, SIZE, f) != SIZE)
    printf("Write Error!\n");
  fclose(f);

  f = fopen("text.dat", "rb");
  printf("Reading\n");
  if(fread(Ar2, 1, SIZE, f) != SIZE)
    printf("Read Error!\n");
  fclose(f);

  printf("Comparing\n");
  if(memcmp(Ar1, Ar2, SIZE))
    printf("Compare Error!\n");

  printf("Success, Hit Enter to exit\n");

  getchar();

  return 0;
}

På min PC med 128MByte RAM kører det fint når det er er kompileret med VC++ 6.0 (og cygwin-gcc og BorlandC). Som du ser skriver og læser det 32Mbyte på en gang. VC++ nægter at kompilere hvis jeg sætter SIZE til 128MByte.
Avatar billede needs Nybegynder
14. november 2003 - 23:24 #26
I mit vsc++ .net 2003 vil den altså ikk... j bruger altså oz long long's / 64 bit variabler... det er nok det.
Avatar billede bertelbrander Novice
14. november 2003 - 23:42 #27
Jeg lavede en ny version der læser/skriver 4*1024*1024 __int64'er, det kører uden problemer, så jeg tror du har en fejl et andet sted. (__int64 er et andet navn for long long.)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE (32*1024*1024/sizeof(__int64)) /* 32MByte */

__int64 Ar1[SIZE];
__int64 Ar2[SIZE];

int main(void)
{
  int i;
  FILE *f;
  for(i = 0; i < SIZE; i++)
    Ar1[i] = rand();

  f = fopen("text.dat", "wb");
  printf("Writing\n");
  if(fwrite(Ar1, sizeof(__int64), SIZE, f) != SIZE)
    printf("Write Error!\n");
  fclose(f);

  f = fopen("text.dat", "rb");
  printf("Reading\n");
  if(fread(Ar2, sizeof(__int64), SIZE, f) != SIZE)
    printf("Read Error!\n");
  fclose(f);

  printf("Comparing\n");
  if(memcmp(Ar1, Ar2, SIZE*sizeof(__int64)))
    printf("Compare Error!\n");

  printf("Success, Hit Enter to exit %d %d\n", SIZE, sizeof(__int64));

  getchar();

  return 0;
}
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