Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hey,

ich habe gerade ein Programm erstell, indem eine CNF-Datei ausgelesen wird. In der CNF-Datei stehen verschiedene Werte in eckigen Klammern.

// In etwa so

wert1 = [123456]

wert2 = [78945]

wert3 = [123456789]

Ich benötige NUR den Wert der Klammern und muss den als String vorliegen haben.

Deshalb habe ich folgendes Programm geschrieben.

============================================================


#define T_BUFFER = 16000;

static in a,b,d,e,zeichen, k_buffer[15];
static int t_buffer[T_BUFFER];


/* Datei einlesen und Größe der Datei in a speichern */
a=_dos_findfirst(dateipfad,_a_normal,&find);
in=open(dateipfad,O_RDONLY|O_BINARY,S_IREAD);
if (a||in==FILEERROR) {
//Fehlermeldung, abbruch blabla. das übliche
} else {
a=(int)find.size;
read(in,&t_buffer,a);
close (in);

/* ab jetzt wirds interresant */
for (b=0;b<a;b++){
if (t_buffer[b]=='['){
for (d=0;d<14;d++){
if (t_buffer[b+d]==']'){
datensatz++; zeichen=0;
for (e=b+1;e<(b+(d-1)); e++){
k_buffer[zeichen]=t_buffer[e];
zeichen++;
}
for (e=zeichen;e<15;e++) k_buffer[e]=0;
d=14; b++;
switch (datensatz){
case 1: strcpy(struktur.wert1, k_buffer);
case n: strcpy(struktur.wertn, k_buffer);
}
}
}
}
}
[/php]

(Ich hoffe mal das ich das jetzt so richtig abgeschrieben habe.)

Das ganze funzt auch prima. Aber gibt es da nicht ne elegantere Möglichkeit. Ich dachte schon an Zeilenweises einlesen der Datei und nach dem ersten aufkommen einer [ und einer ] suchen. Aber damit würde ich höchstens ein paar Zeilen sparen.

Hat jemand nen besseren Vorschlag?

MVG

need-some-blood

Geschrieben

Was heißt für dich eleganter?

ein Problem wird wahrscheinlich sein, wenn das File größer als

16000 Byte ist.

Warum schließt du das File und suchst im Speicherblock?

Man könnte doch auch blockweise lesen (z.B. 512 Byte) und den

File Pointer zum Werte auszulesen benutzen. Vielleicht ist es dann

auch möglich die Schleifenschachtelung etwas zuminimieren.

Ansonsten sehe ich kein Problem, es sei denn während des Parsens tretten

Fehler auf oder die Syntax der CNF-Files variiert.

Wenn, die Werte sich immer an der gleichen Stelle befinden

könnte man doch über eine Offset-Parameter nachdenken.

Geschrieben

Danke für die Antwort wenigstens einer. :uli

Tja was heißt für mich eleganter? Also ich weiß zwar das das ganze Funzt. Aber ich bin damit nicht zufrieden. Das ganze muss doch wesentlich besser gehen. Aber ich beantworte dir erstmal deine Fragen.

ein Problem wird wahrscheinlich sein, wenn das File größer als

16000 Byte ist.

Sehr unwarscheinlich. Das ganze ist ne Konfigurationsfile, und da sind 16Kb schon verdammt viel. Und wenn es das ganz doch mal überschreitet, dann kann ich ja einfach die Konstante erhöhen.

Warum schließt du das File und suchst im Speicherblock?

Weil wir mit nem Multi-Tasking-System arbeiten. Ich lese damit zyklisch aus der Datei, und da ich nicht zehn mal die gleiche Datei geöffnet haben möchte, schließe ich sie wieder. Ausserdem habe ich mal gelernt, dass man keine Dateien offen liegen lässt. Ein Absturz und die Datei ist möglicherweise beschädigt. ;)

Man könnte doch auch blockweise lesen (z.B. 512 Byte) und den

File Pointer zum Werte auszulesen benutzen. Vielleicht ist es dann

auch möglich die Schleifenschachtelung etwas zuminimieren.

a) siehe oben

B) Wenn ich das täte müsste ich jedesmal überprüfen, ob ich die gleiche Anzahl von geöffneten und geschlossenen Klammer habe. Wenn nicht, dann müsste ich den nächsten Block in einen anderen Speicher lesen und den geteilten Datensatz wieder mühsam zusammenfügen. Ich weiß nicht ob dies nicht evtl sogar ein Mehraufwand wäre?

Die Datensätze varieren (Länge, Größe, Inhalt) aber nicht die Bezeichnungen. Diese sind nur unterschiedlich lang.

Ich hoffe mal dir deine Fragen beantwortet zu haben. Evtl kommen wir ja doch noch auf ein besseres Ergebniss.

MVG

need-some-blood

Geschrieben

Klingt interessant. Mal seh'n wo die Reise hingeht.

Also, mit schliessen meine ich nicht das File die ganze Zeit auf zulassen, sondern

nur bis alle Werte ausgelesen sind.

Wenn deine Routine in mehreren Threads aufgerufen wird, gibt's glaube ich

Probleme mit static Buffer.

Beispiel:

char sBuffer[512];

char *p;

FILE* pF;

long n;

long nPos;

long nPosBracketOpen;

long nPosBracketClose;

char sWert[128];

pF=fopen(....);

while(feof(pF))

{

n=fread(sBuffer,sizeof(char),sizeof(sBuffer),pF);

p=sBuffer;

while((p-sBuffer)<=n)

{

//if( suchen==true)

{

nPos=fseek(pF,0,SEEK_CUR);

fseek(pF,nPosBracketOpen+1,SEEK_SET);

fread(sWert,sizeof(char),nPosBracketClosenPosBracketOpen,pF);

fseek(pF,nPos,SEEK_SET);

}

}

}

fclose(pF);

ich weiß geht alles auch mit std::ifstream (fopen,fseek,fclose ...)

das geht nartürlich nur wenn sich die Datei nicht laufend ändert (jedenfalls weiß ich das nicht so genau)

Was ich als Gedankenanstoß geben wollte ist, dass das Lesen der Werte

im File geht und das Parsen im Buffer. Die Verbindung beider über File Position.

Die Größe des Buffers klein gehalten werden kann.

PS: Quellcode habe ich nicht aus probiert, kann sein das ich was vergessen habe

Geschrieben

Vielleicht helfen dir Library's für das Parsen weiter:

GRETA: http://research.microsoft.com/projects/greta/

BOOST: http://www.boost.org/

lex yacc: http://www.monmouth.com/~wstreett/lex-yacc/lex-yacc.html

hier noch ein vergleich zwischen GRETA & BOOST (MS lastig)

http://research.microsoft.com/projects/greta/regex_perf.html

In der C-Library gibt es nartürlich auch fscanf und sscanf

In der stl ist es dann ofstream mit dem operator >>

und stringstream (bin mir aber nicht ganz sicher)

Nun das sollte fürs Erste reichen.

Die Library's wirken etwas übertrieben für eine solche "trivale"

Aufgabe, aber prinzipiell anwendbar. Ich bin mir aber nicht sicher

inwieweit diese Thread sicher sind.

Würde mich ja interessieren was du nun gewählt hast und

welche Erfahrung du gemacht hast. Oder war's nur ein Schuß ins Blaue?

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...