Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Datei lesen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
21.01.2009, 14:09 Uhr
filth



Hallo,

ich komme an einer Stelle nicht weiter:

wie kann ich eine Datei von der Festplatte zeilenweise in den Speicher lesen?


C++:
char cstring[1024];
f.open("C:\\test.txt", ios::in);
    while (!f.eof())
    {
        f.getline(cstring, sizeof(cstring));        
        cout << cstring << endl;        
    }
    f.close();



funktioniert an sich, aber die Zeilenlänge kann ja variieren. Was ist zb wenn ich eine Zeile mit 5000 Zeichen einlesen will?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
21.01.2009, 19:32 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hi,

kommt nun drauf an ob du binär oder textdateien hast, ich denke mal, da du zeilenweise einlesen willst, steht in den zeilen auch lesbarer text. dann würde ich einfach std::string verwenden:


C++:
string line;
f.open("C:\\test.txt", ios::in);
    while (!f.eof())
    {
        getline(f, line);
        cout << line << endl;        
    }
    f.close();


--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
21.01.2009, 21:09 Uhr
0xdeadbeef
Gott
(Operator)



C++:
while(!f.eof())


ist kein wirklich guter Ansatz, auf das Dateiende zu prüfen - das eofbit wird erst gesetzt, nachdem ein Leseversuch hinter das Ende der Datei fehlgeschlagen ist. Dementsprechend wird dir auf diese Art die letzte Zeile zweimal ausgegeben.

Besser geht das so:

C++:
while(getline(f, line)) {
  cout << line << endl;
}


getline gibt den Stream zurück, und der hat einen operator void*(), der NULL zurückgibt, wenn ein failbit gesetzt ist (was eof mit einschließt).
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.01.2009, 23:55 Uhr
filth



Hallo,

vielen Dank. So klappt es schon mal.

Ich habe aber direkt eine Frage im Anschluß - Ich möchte die Datei einlesen, um diese über das Netzwerk zu senden. Für diese Fälle sollte man die Datei binär einlesen - wie mache ich das?
Außerdem bin ich noch auf ein anderes Problem gestossen, und zwar sieht die Empfängerseite so aus:


C++:
    char buffer[256];        // On the stack

    int nret = recv(theSocket,
        buffer,
        256,        // Complete size of buffer
        0);



Ich habe mir jetzt eine Struktur gebaut, die vor der eigentlichen Datei gesendet wird, so kenne ich dann schon mal die Größe der Datei, wie kann ich aber nun den Empfangsbuffer entsprechend vergrößern? Ich kenne momentan keine Methode, um die Größe eines Arrays zur Laufzeit fest zu legen.

Da gibt es wahrscheinlich eine andere Lösung - hat jemand eine Idee?

Mein Notplan wäre jeweils 1024 Zeichen aus der Datei in einer Struktur zu senden, bei den letzten n < 1024 Zeichen dann mit einem entsprechenden Feld dem Empfänger mit zu teilen, wieviele Zeichen relevant sind. Diese Lösung erscheint mir aber irgendwie nicht schön.

Grüße
Alex

Dieser Post wurde am 21.01.2009 um 23:59 Uhr von filth editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
22.01.2009, 00:00 Uhr
0xdeadbeef
Gott
(Operator)


Datei binär einlesen:

C++:
std::ifstream in("datei.dat", std::ios::in | std::ios::binary);



Arrays variabler Länge:

C++:
int x;
char *array;

std::cin >> x; // x variabel

array = new char[x];

// array benutzen

delete[] array;


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
23.01.2009, 09:39 Uhr
filth



Es scheint zu funktionieren.

Vielen dank, mir ist sehr geholfen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
25.01.2009, 12:57 Uhr
filth



Hallo,

es gibt noch ein kleines Problem :


C++:
                        int length;
            char * buffer2;

            ifstream is;
            is.open (fileToSend.c_str(), ios::binary );

            // get length of file:
            length = getFileSize(fileToSend);

            // allocate memory:
            buffer2 = new char [length];

            // read data as a block:
            is.read (buffer2 ,length);
            is.close();

            cout << "will send this buffer : " << endl;
            cout << buffer2;
            cout <<endl;





C++:
//returns filesize
int getFileSize(std::string fileName)
{
    int result = 0;

    ifstream is;
    is.open (fileName.c_str(), ios::binary );

    // get length of file:
    is.seekg (0, ios::end);
    result = is.tellg();
    
    is.close();

    return result;
}




In der Datei, die gelesen wird steht:

Code:
123

ffff
gggg
XXX



Der eingelesene Buffer beinhaltet jedoch:

Code:
will send this buffer :
123

ffff
gggg
XXX²²²²½½½½½½½½¯■¯■¯■



Woher kommen diese Sonderzeichen nach den letzten XXX? Ich vermute, dass die Länge der Datei falsch ermittelt wird, oder?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
25.01.2009, 18:32 Uhr
0xdeadbeef
Gott
(Operator)


Wenn du das ganze als C-String benutzen willst, musst du am Ende ein Zeichen mehr anfordern und auf Null setzen - den Sentinel. ifstream::read liest stumpf einen Block Daten aus, es weiß nicht, dass du da einen String einlesen willst.

Übrigens, wenn du einfach die ganze Datei auf einmal einlesen willst:

C++:
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>

int main() {
  std::ifstream in(__FILE__);
  std::istream_iterator<char> end;

  in.unsetf(std::ios::skipws);

  std::string s(std::istream_iterator<char>(in), end);

  std::cout << s;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
25.01.2009, 22:24 Uhr
filth



Und nochmals danke
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
27.01.2009, 23:23 Uhr
filth



Hallo,

ich schon wieder.
Nun funktioniert das Lesen mit dem \0 terminierten String.

Es funktioniert bei allen Dateien, die anscheinend keine Sonderzeichen beinhalten.

Sobald ich versuche zb eine .jpg einzulesen, werden nur ein paar Zeichen gelesen:


Code:
will send this buffer :
Ï Ó



Hier nochmal zur Sicherheit der Lese-Block:


C++:
                        ifstream is;
            is.open (fileToSend.c_str(), ios::binary );

            // get length of file:
            length = getFileSize(fileToSend);

            // allocate memory:
            buffer2 = new char [length+1];

            // read data as a block:
            is.read (buffer2 ,length);
            is.close();

            buffer2[length] = '\0';

            cout << "will send this buffer : " << endl;
            cout << buffer2;
            cout <<endl;



Ihr habt mit Sicherheit wieder eine Idee

Grüße
Alex
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: