Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Meandor

Frischling

  • »Meandor« ist der Autor dieses Themas

Beiträge: 55

Wohnort: Oberhausen

Beruf: Student

  • Private Nachricht senden

1

11.04.2005, 14:43

aus Dateien lesen

Hi

Ich würde gerne wissen wie man eine Ascii Text Datei vernüpftig einliest.

FILE *Datei;
Datei = fopen("ta_datei.txt","r");

so und jetzt habe ich eine zusammenhängende Textdatei zB.:
1234....12:40:12....08AFTX.....12.4.2005
ich kann also schlecht mit so was wie
dat_ein.open(dateiname.c_str(), ios_base::in);
dat_ein>>nr >>Uhrzeit>>Paket>>Datum

die Dinge einlesen weil diese zusammenhängen!
Ich kenne aber den Dateiaufbau! Also nach 10 Zeichen kommt das Datum nach 5 Zeichen das und das usw...

Wie kann man denn so etwas lösen??
Ich habe schon gelesen das es die Funktion gibt fscanf
aber ich finde keine passenden Beispiele die mir weiter helfen vielleicht geht das ja auch irgendwie anders zb:
fgets(buf,80,Datei);
char wort[1];
strncpy(wort,&buf,len);
aber damit müsste ich ja wieder mit char Arrays arbeiten gibt es denn keine Möglichkeit direkt in Strings zu speichern

Also ich drehe mich im Kreis. Kein mir jemand bitte weiterhelfen und mir vielleicht auch mal ein vernüpftiges Beispiel geben wie man das macht!

Jens

2

11.04.2005, 14:50

versuchs mal mit
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );

wenn du weisst wie die datei aufgebaut ist sollte der rest nicht mehr so schwer sein.

hier noch ein link zum ents. eintrag im msdn:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_fread.asp

weigo

Treue Seele

Beiträge: 234

Wohnort: Deutschland

  • Private Nachricht senden

3

11.04.2005, 15:26

Zeilenweise auslesen könntest du so:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <fstream>

const int BUFFER_SIZE = 4096;
std::string str_file = "Dateiname.txt";

std::ifstream if_config( str_file.c_str(), std::ios::in );
    
char c_input[ BUFFER_SIZE ];

if_config.getline( c_input, BUFFER_SIZE );
m_strSourcePath = c_input;
if_config.getline( c_input, BUFFER_SIZE );
m_strTargetPath = c_input;
if_config.getline( c_input, BUFFER_SIZE );
m_strTargetFormat = c_input;

if_config.close();


Hast du mehrere Wörter in einer Zeile und hast als Seperator z.B. ein Leerzeichen, dann kannst du den strstream nutzen:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <fstream>
#include <strstream>

char chr;
std::ifstream is( "hallo.txt", std::ios::in );        

std::stringstream str_stream;

while ( is.good() )    
{
    chr = is.get();     
    str_stream << chr;
}

std::string a;
str_stream >> a;
std::string b;
str_stream >> b;
std::string c;
str_stream >> c;

is.close();

Beispiel:
hallo.txt:
Hallo du da!

Output:
a hat den Wert: Hallo
b hat den Wert: du
c hat den Wert: da!

Till

Alter Hase

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

4

11.04.2005, 16:32

Gibt es einen Grund, dass du es mit FILE* machst und nicht mit "fstream" wie weigo gezeigt hat?
Und "fscanf" ist ganz einfach (und dann in deinem Fall auch zu raten), sofern du mit "printf" oder "scanf" umgehen kannst (hach, die alten C-Zeiten *schmacht*).
Zum Beispiel liest

C-/C++-Quelltext

1
2
3
4
5
char string1[1024], string2[1024], string3[1024];
int int1;
unsigned int uint1;
FILE *pFile = fopen("test.txt","r");
fscanf(pFile,"%s%d%s%s%u",string1,&int1,string2,string3,&uint1);


Hierbei werden nacheinander die strings und die anderen Typen "eingelesen".

Aber da wir heute in einer Welt aus C++ leben, würde ich einfach stringstreams verwenden (wieso auch nicht?), die dann schön mit dem Operator >> zusammenarbeiten und "wissen", wie viel einzulesen ist (doch Vorsicht mit den Strings, wenn sie nicht Nullterminiert sind!!!)
DOMINVS ILLVMINATIO MEA
---
Es lebe unmanaged Code!
---
>> Meine Uni <<

weigo

Treue Seele

Beiträge: 234

Wohnort: Deutschland

  • Private Nachricht senden

5

11.04.2005, 16:40

Die Zeilenlänge muss nicht genau bekannt sein und jede Zeile muss auch nicht gleich lang sein, aber der Buffer muss eben groß genug sein.

I.d.R. sollte man wissen wie lang eine Zeile ungefähr ist.
Man sollte auf keinen Fall einfach mal einen x-beliebig großen Buffer im Stack allokieren, wenn dies nicht unbedingt nötig ist.
4 KB sollten im Normalfall ausreichen.

Meandor

Frischling

  • »Meandor« ist der Autor dieses Themas

Beiträge: 55

Wohnort: Oberhausen

Beruf: Student

  • Private Nachricht senden

6

11.04.2005, 20:37

und wie weiter

also ersteinmal danke für die vielen Mails von euch! Ich habe das aber nicht ganz verstanden eure Codes!
OK weigo ich will das jetzt mit streams machen wie du gesagt hast!Habe das ja auch schon mal probiert aber der liest eben dann die ganze Zeile ein(aber ich weiß das ab Stelle 11 mein Datum kommt!!)

Ich habe in einer Zeile mehrere Wörter plus Datum Uhrzeit usw. wo gebe ich denn dem Programm mit das er bis zum Buchstaben fünf (also zur Stelle fünf in der Zeile das in den Stream schreiben soll??)

Solange er das Ende der Zeile erreicht hat!

Wichtig ist aber dass das FILE oder der Stream offen bleiben muss, damit es beim nächsten Aufruf sich die nächste Zeile sich schnappt und nicht wieder von vorne anfängt. Und das gleiche Datum und Stellplatz ausliest.

2.Frage
c=strptime(cm_zeit,"%Y-%m-%d %H:%M:%S",&tm_zeit);
meldezeit=(double)mktime(&tm_zeit);

wieso kennt visual c++ die funktion strptime() nicht? Ist das eine spezielle UNIX Funktion habe die Funktion aus einem anderen Beitrag gefunden klappt auch nicht. also das eingelesene Datum soll als UTC Zeit umgeformt werden!
Wie mache ich das, wenn ich das Datum als String siehe Frage 1 eingelesen habe. also mit mktime bin ich doch schon auf dem richtigen Dampfer oder????

Ich hoffe einer von euch hat schon mal so was gemacht.
Ich danke schon mal allen die mir irgendwie weiterhelfen könnten.
Würde euch gerne was ausgeben oder euch mal auf ein Bier einladen.
Jens

Till

Alter Hase

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

7

11.04.2005, 20:51

Re: und wie weiter

Zitat von »"Meandor"«


2.Frage
c=strptime(cm_zeit,"%Y-%m-%d %H:%M:%S",&tm_zeit);
meldezeit=(double)mktime(&tm_zeit);

wieso kennt visual c++ die funktion strptime() nicht? Ist das eine spezielle UNIX Funktion habe die Funktion aus einem anderen Beitrag gefunden klappt auch nicht.


Versuch mal "strftime", damit müsste es gehen!
DOMINVS ILLVMINATIO MEA
---
Es lebe unmanaged Code!
---
>> Meine Uni <<

weigo

Treue Seele

Beiträge: 234

Wohnort: Deutschland

  • Private Nachricht senden

8

11.04.2005, 21:41

Könntest du vielleicht ein Beispiel deiner Textdatei posten?
Wenn die Wörter ohne Trennzeichen sind, dann musst du einfach einen char anlegen, der z.B. 5 Zeichen beinhalten kann.

Quellcode

1
2
3
4
5
6
7
8
9
10
#include <fstream>

const int BUFFER_SIZE = 5;
std::string str_file = "Dateiname.txt";

static std::ifstream if_config( str_file.c_str(), std::ios::in ); // durch das static bleibt die Datei solange geöffnet bis du sie explizit mit close schließt oder das Programm beendet wird. Das ist nur sinnvoll, wenn du beim Lesen die Funktion verlassen solltest und später die Funktion erneut aufrufst, um aus der Datei weiter zu lesen. Ansonsten brauchst du kein static.
   
char c_input[ BUFFER_SIZE ];

if_config.getline( c_input, BUFFER_SIZE ); // ließt genau 5 Zeichen, evtl. springt er in die nächste Zeile, das musst du mal testen, dann müssten wir eine andere Methode nehmen.


Wenn die Informationen getrennt sind, z.B. Zeit Datum usw. dann kannst du doch einfach das zweite Beispiel mit dem stringstream verwenden. Du kannst die Daten aus dem string dann wieder in eine Zahl konvertieren, z.B. mit atoi !

PD

unregistriert

9

12.04.2005, 14:24

Naja, man kann auch einfach die ganze zeile in einen string lesen (c oder c++ ist relativ egal) und dann weiß man z.B. das bei str[0] der erste datensatz beginngt, bei str[7] der zweite usw. Das ließe sich dann in einer Schleife oder so kopieren und mann kann sogar direkt die Punkte abschneiden... Ich persönlich würde aber ein anderes Trennzeichen wie das | empfehlen weil dann ist es völlig egal wo sich die Datensätze befinden, man sucht einfach nach dem | ...

Till

Alter Hase

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

10

12.04.2005, 18:01

Also am Besten wäre es, wenn du erst mal genau sagst, was du über die Datei weißt!

So wie ich das jetzt verstehe, weißt du, wo (in Bytes), also bei welchem "offset" vom Dateianfang die jeweiligen Daten stehen, die du haben willst, richtig?

Dann ist die Frage, was zwischen den "Daten" ist, also ob es z.B. nur Nullen sind oder ob es irgendetwas undefiniertes ist oder irgendein anderer Mist, den du nicht brauchst. Dann stellt sich natürlich auch die Frage, ob du immer die Abstände kennst, also z.B. "nach 5 Bytes kommt a, zehn Bytes später kommt b, sieben Bytes später kommt c, usw." oder ob du, wie oben erwähnt, die offsets kennst: "an Position 5 kommt a, an Position 15 kommt b, an Position 22 kommt c, usw."

Schließlich muss noch geklärt sein, wie erkannt wird, wann ein "Datenelement" vorbei ist, was natürlich mit den Trennzeichen zusammenhängt.
Wenn du dies alles berücksichtigst, müsste es klappen, also gib' uns einfach die konkreten Infos!

Und falls du etwas wissen willst:

Quellcode

1
int fseek( FILE *stream, long offset, int origin );


Diese Funktion setzt den Dateizeiger an die gewünschte Position. Wenn du mit C++ und ifstream arbeiten willst, dann gibts: ifstram::seekg (Schau einfach in der MSDN danach)

Ich hoffe, ich konnte dir helfen!
Sag' bescheid, wenn du Fragen hast ... :huhu:
DOMINVS ILLVMINATIO MEA
---
Es lebe unmanaged Code!
---
>> Meine Uni <<

Werbeanzeige