Toon posts:

[C++] bestand inlezen in buffer *

Pagina: 1
Acties:
  • 123 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Hallo

Ik ben bezig met een prog waarmee je rechtstreeks bestanden kan sturen naar een bepaald ip. Nu begon ik met het doornemen van de filestreams, en ik probeerd wat simpels te maken. Ik heb nu het volgende
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
#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

const char * filename = "1naleinste.cpp";

int main () 
{
  char * buffer;
  long size;
  ifstream file (filename, ios::in|ios::ate);
  size = file.tellg();
  cout << size << endl;
  file.seekg (0, ios::beg);
  buffer = new char [size];
  file.read (buffer, size);
  file.close();
  cout << "File is in buffer gezet\n\n";
  cout << buffer << endl << endl;
  delete[] buffer;
  system("pause");
  return 0;
}

Nu verwacht ik als uitvoer de inhoud van een cpp bestand. Het volgende krijg ik als uitvoer:

Grootte van bestand in bytes
File is in buffer gezet
De inhoud van het bestand

Druk op een toets om verder te gaan...

Nu wil ik dat de grootte van het bestand wordt weggelaten, als ik de regel cout<<size<<endl; weghaal krijg ik echter na de uitvoer van buffer een vage regel die nergens op en bij iedere keer compilen is dat iets anders. Meestal is het een soort pad naar de map van MSVC++ of DEV-C++ maar soms is het een deel van de computernaam en soms iets waarvan ik niet weet wat het is. Dit krijg ik nu

in;C:\Dev-Cpp\lib\gcc-lib\mingw3?

en soms krijg ik een regel dat met MSVC++ te maken heeft terwijl ik dat helemaal niet gebruik, gebruik nl Dev-C++. Iemand een idee hoe het komt

edit:
Sorry voor de slechte titel, zie ik nu pas. Kan een mod m veranderen? |:(

[ Voor 8% gewijzigd door Verwijderd op 26-10-2003 11:54 ]


  • _Squatt_
  • Registratie: Oktober 2000
  • Niet online
Verwijderd schreef op 26 October 2003 @ 11:47:


Nu wil ik dat de grootte van het bestand wordt weggelaten, als ik de regel cout<<size<<endl; weghaal krijg ik echter na de uitvoer van buffer een vage regel die nergens op en bij iedere keer compilen is dat iets anders.
Je buffer mist een sluitend '\0' char. Nu wordt alles wat er achter je buffer in het geheugen staat ook naar cout geschreven. Die '\0' zul je dus zelf op de juiste plek toe moeten voegen:


C++:
1
2
3
4
5
file.read( buffer, size);

// gcount() geeft het aantal gelezen bytes van de vorige read() operatie.

buffer[file.gcount()] = 0;


Om plaats te hebben voor de afsluitende '\0' zul je 1 char extra moeten reserveren.

"He took a duck in the face at two hundred and fifty knots."


  • dexter07051982
  • Registratie: November 2001
  • Laatst online: 11-07 22:38
krijg je trouwens wel de juiste "size"?
(zal wel anders haal je het niet weg)
maar waarom hoef je daarvoor niet eerst naar het einde van het bestand te gaan? Dus met ".seekg(0,ios::end)".
voor zover ik weet krijg je met ".tellg" de huidige positie van de leespointer en niet auto het einde van de file.

en is deze dan nu niet ondgedifinieerd waardoor die juist een hele grote waarde heeft en dus een te grote buffer maakt en dus te veel uitschrijft van het geheugen?

Verwijderd

Topicstarter
De waarde die ik krijg is wel juist, want ik krijg het aantal bytes dat een bestand groot is. Nu ga ik even proberen om de buffer size+1 te maken
en helemaal op het eind zelf buffer[size]='\0' toe te voegen

Zijn er vandaag btw geen mods ofzo :?

edit:
Ik heb nu het volgende:

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
#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

const char * filename = "1nakleinste.cpp";

int main () 
{
  char * buffer;
  long size;
  ifstream file (filename, ios::in|ios::ate);
  size = file.tellg();
  //cout << size << endl;
  file.seekg (0, ios::beg);
  buffer = new char [size+1];
  file.read (buffer, size);
  buffer[size]='\0';
  file.close();
  cout << "File is in buffer gezet\n\n";
  cout << buffer << endl << endl;
  delete[] buffer;
  system("pause");
  return 0;
}


de buffer is 1 groter dan size. En in de laatste element sluit ik de buffer af met een '\0'. En toch gebeurt hetzelfde :?
En het vage is dat als cout<< size << endl; geen commentaar is en dat hij dus de grootte van size afdrukt dat dat opeens verdwijnt.

[ Voor 73% gewijzigd door Verwijderd op 26-10-2003 18:53 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
Verwijderd schreef op 26 October 2003 @ 18:47:
Zijn er vandaag btw geen mods ofzo :?
Vroeg ik me ook al af. Heb je een Topic Report gemaakt? Anders bestaat er de kans dat ze je bericht niet lezen, namelijk. (TR maak je met dat handje-icon linksboven).

Sowieso is het prettig als je dan gelijk een suggestie doet voor een goede nieuwe titel, want "Vreemd probleem" zegt eigenlijk niets. (90% van de topics zijn problemen en als je het hier plaatst begrijp je waarschijnlijk zelf niet wat er mis gaat - anders had je het al opgelost - dus is het ook bijna automatisch vreemd.) Iets als "[C++] Bestand geheel inlezen in buffer" geeft bijvoorbeeld beter weer waar je topic over gaat.

  • _Squatt_
  • Registratie: Oktober 2000
  • Niet online
dexter07051982 schreef op 26 October 2003 @ 18:22:
maar waarom hoef je daarvoor niet eerst naar het einde van het bestand te gaan? Dus met ".seekg(0,ios::end)". voor zover ik weet krijg je met ".tellg" de huidige positie van de leespointer en niet auto het einde van de file.
Dr HenDre gebruikt:
C++:
1
ifstream file( filename, ios::in | ios::ate)

Door de ios::ate staat de leespointer aan het einde van het bestand.
edit:
Je programma uit je laatste edit werkt hier prima, ik zie zo snel niet wat daar mis aan is.

[ Voor 18% gewijzigd door _Squatt_ op 26-10-2003 19:05 ]

"He took a duck in the face at two hundred and fifty knots."


Verwijderd

Topicstarter
Ok ik gebruik de source die ik als laatst gegeven had, enige wat ik verander is de bestandsnaam. Ik gebruik nu een andere bestand(de source van het prog zelf). Dit is de uitvoer:
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
File is in buffer gezet

#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

const char * filename = "filestream.cpp";

int main ()
{
  char * buffer;
  long size;
  ifstream file (filename, ios::in|ios::ate)
  //file.open(filename);
  size = file.tellg();
  //cout << size << endl;
  file.seekg (0, ios::beg);
  buffer = new char [size+1];
  file.read (buffer, size);
  buffer[size]='\0';
  file.close();
  cout << "File is in buffer gezet\n\n";
  cout << buffer << endl << endl;
  delete[] buffer;
  system("pause");
  return 0;
}
rosoft Visual Studio\VC98\l

Druk op een toets om door te gaan. . .


op het moment dat ik zoals gezegd de 2 commentaar strepen bij cout<< size.... weghaal krijg ik het volgende

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
565
File is in buffer gezet

#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

const char * filename = "filestream.cpp";

int main ()
{
  char * buffer;
  long size;
  ifstream file (filename, ios::in|ios::ate);
  //file.open(filename);
  size = file.tellg();
  cout << size << endl;
  file.seekg (0, ios::beg);
  buffer = new char [size+1];
  file.read (buffer, size);
  buffer[size]='\0';
  file.close();
  cout << "File is in buffer gezet\n\n";
  cout << buffer << endl << endl;
  delete[] buffer;
  system("pause");
  return 0;
}


Druk op een toets om door te gaan. . .

opeens is de rare regel verdwenen(een regel wat naar MS Visual Studio verwijst terwijl ik dit met Dev-C++ compile)

[ Voor 37% gewijzigd door Verwijderd op 26-10-2003 19:14 ]


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Voeg eens ios::binary toe aan het lijstje in de ifstream constructor.. De size die je krijgt klopt wel, maar wat je leest met read is niet precies wat in de file staat. End of line tekens als CR/LF/CRLF worden namelijk allemaal omgezet in LFs (tenminste in VC, weet niet wat de standaard hier voor is als ie al bestaat). Aangezien windows files normaalgesproken CRLF gebruiken, wordt voor elke CRLF de CR weggehaald. Daardoor krijg je minder bytes terug dan 'size', om precies te zijn evenveel als het aantal end of lines, 27 in jouw geval en dat is ook precies het aantal bytes 'troep' die je overhoud (strlen("rosoft Visual Studio\VC98\l")==27) :).

www.madwizard.org


Verwijderd

Topicstarter
binairy had ik al geprobeerde werkte ook niet. Is er misshien nog een andere manier om het uit te lezen en in een buffer op te slaan. Het meot wel exact hetzelfde zijn, ik wil het later verzenden en met een .cpp is dat niet erg, maar met .exe ofzo wel

  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Bij mij werkt binary prima hoor.. Zowieso zou ik voor grote bestanden niet alles in 1 buffer lezen, maar een paar KB per keer ofzo inlezen en versturen.

www.madwizard.org


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
Uit m'n hoofd
C++:
1
2
3
4
5
6
7
8
#include <iostream>
#include <fstream> 
int main()
{
  const char * filename = "1naleinste.cpp";
  ifstream in(filename);
  std::cout << in.rdbuf() << std::endl;
}

[ Voor 15% gewijzigd door MSalters op 27-10-2003 13:53 ]

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


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 26 October 2003 @ 18:47:
Zijn er vandaag btw geen mods ofzo :?
offtopic:
Mogen we ook een keer toevallig een machtsvacuum van 7-8 uur laten vallen :)

Professionele website nodig?


Verwijderd

Topicstarter
Huh vreemd, ik weet echt 100% zeker dat dit met binary niet werkte. Ik had het in het begin met binary het werkte niet, dus ik haalde het weg en nu werkt het wel :s

@curry684 Vooruit dan maar :9

ik snap het al, ik had toen met binary de afsluitende \0 niet. Nu werkt ie idd. Thnx 8)7

Btw, waarom niet een grote bestand in de buffer?

[ Voor 29% gewijzigd door Verwijderd op 27-10-2003 15:05 ]


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Verwijderd schreef op 27 October 2003 @ 15:00:
Btw, waarom niet een grote bestand in de buffer?
Omdat het veel efficienter is het in delen in te lezen, en zeker minder geheugen kost.. Stel je verstuurd een bestand van 15MB, dan moet ie 15 MB geheugen alloceren. Eigenlijk is dat nergens voor nodig want met een buffer van zeg 64 kb kan je de boel net zo snel versturen maar met een fractie van het geheugengebruik. Veel meer werk is het niet trouwens.

www.madwizard.org


Verwijderd

Topicstarter
ok, nog een probleem. Nu heb ik er een functie van gemaakt en iets uitgebreider gemaakt.

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
34
35
36
#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

char* leesBestand (const char * filename) 
{
  char * buffer;
  long size;
  ifstream file (filename, ios::in|ios::ate|ios::binary);
  
  if(file.fail())
  {
    cout<<endl<<"Error, bestand "<<filename<<" kon niet worden geopend\n";
    return 0;
  }
  
  size = file.tellg();
  file.seekg (0, ios::beg);
  buffer = new char [size+1];
  file.read (buffer, size);
  buffer[size]='\0';
  file.close();
  return buffer;
}

int main()
{
    char padNaarBestand[999];
    cin>>padNaarBestand;
    char* bestand = leesBestand(padNaarBestand);
    cout << endl << bestand << endl << endl;
    delete[] bestand;
    system("pause");
}


Nu lukt het inlezen van gewone bestanden wel, maar als ik bv een exe of iets anders wil inlezen waar niet alleen plain text in staat, dat doet ie dat niet. Dan krijg ik gewoon een paar lege regels en dat was het, en terwijl binary er juist voor moet zorgen dat ook dat goed ingelezen(en afgedrukt) kan worden. Of heb ik dat mis?

edit:
Ik weet dat ik het inlezen van de pad niet zo netjes doe, maar dat verander ik later wel. Dat is geen punt.

[ Voor 12% gewijzigd door Verwijderd op 27-10-2003 18:13 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je gebruikt een C-style string, waarvan het eind wordt aangegeven met een \0 character. De \0 komt in textbestanden niet voor, maar in binary bestanden wel. Je uitvoer stopt dus op het moment dat die \0 wordt tegen gekomen, en daar zit 'm dan ook de fout, niet bij het inlezen.

Je zou bijvoorbeeld een std::string kunnen gebruiken, die heeft geen moeite met \0 characters

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • _pjotr_
  • Registratie: Juni 2003
  • Laatst online: 20-03-2024
Je geeft buffer terug als return waarde. Buffer is een lokale variabele. Als de functie is afgelopen is buffer niet langer geldig (buiten de scope). Behalve vreemd gedrag lijdt een dergelijke constructie tot mogelijke stack/heap corruptie.
Bovendien kan een stl type als string of array je veel werk uit handen nemen.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
_pjotr_ schreef op 27 October 2003 @ 22:03:
Je geeft buffer terug als return waarde. Buffer is een lokale variabele. Als de functie is afgelopen is buffer niet langer geldig (buiten de scope). Behalve vreemd gedrag lijdt een dergelijke constructie tot mogelijke stack/heap corruptie.
Niets van waar. Je kunt prima lokale variabelen by-value (!) retourneren. De pointer verwijst naar dynamisch gealloceerd geheugen dat gewoon geldig blijft (maar natuurlijk wel vroeger of later ergens vrijgegeven moet worden). Misschien moet je maar eens een goed C++ boek of tutorial doornemen. ;)
Bovendien kan een stl type als string of array je veel werk uit handen nemen.
Een STL string (of vector<char>) is inderdaad wel handig; een STL array bestaat niet.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 18:33
_pjotr_ schreef op 27 October 2003 @ 22:03:
Je geeft buffer terug als return waarde. Buffer is een lokale variabele. Als de functie is afgelopen is buffer niet langer geldig (buiten de scope).
Dat verhaalt geldt alleen als de buffer zelf op de stack is gealloceerd. Hier wordt de buffer op de heap gealloceerd, en een pointer naar die buffer teruggegeven.

Niets mis mee dus :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
hehe, volgens mij is dit een beetje boven mijn niveau, maar ik zal eens kijken wat ik ermee kan. :)
Pagina: 1