| Autor |
C: Dateizeiger an den Anfang der nächsten Zeile verschieben? |
|
milch
Aktiv  Dabei seit: 23.02.2009 Mitteilungen: 296
Aus:
 |     Themenstart: 2012-08-22 18:35
|
Hallo,
ich lese (oder will lesen) mittels einer einfachen Routine den Inhalt einer Textdatei (die durchaus ein paar 100 MB groß sein kann) aus, genauer suche ich nach bestimmten Zeilen die Informationen enthalten die ich auswerten will.
Da diese Zeilen alle mit einem bestimmten Wort anfangen, ist meine Idee folgende:
Ich lese den ersten Buchstaben der Zeile ein (mit fscanf) wenn der schon nicht passt, will ich direkt zur nächsten Zeilen spingen, wenn er passt dann lese ich das nächste Zeichen ein usw. nach dem 6. Zeichen weiß ich sicher das ich in einer der Zeilen gelandet bin die ich auswerten will und wie ich das dann machen kann ist auch klar (oder wäre es schneller hier direkt den ersten/ganzen String der Zeile einzulesen und dann mit dem Suchstring zu vergleichen?).
Mein Problem ist jetzt das verschieben des Zeigers in die nächste Zeile.
Ich könnte jetzt weiter Buchstabe für Buchstabe einlesen (oder auch hier stringweise, falls das schneller geht?) bis zum Zeilenende, da ich ja nicht genau weiß was in den anderen Zeilen so steht und vorallem wieviele Zeichen da noch kommen. Geht das auch einfacher bzw. schneller?
Gibt es eine Funktion mit der ich den Rest des Dateistreams (allerdings nur bis EOL) überspringen kann, mir war so als gäbe es da etwas (irgendwas mit FLUSH oder so)?
[ Nachricht wurde editiert von milch am 22.08.2012 18:37:07 ]
|
Profil
Quote
Link |
Otis
Senior  Dabei seit: 06.10.2007 Mitteilungen: 899
Aus: Stralsund
 |     Beitrag No.1, eingetragen 2012-08-22 18:49
|
Hi,
mit fseek kann man den Dateizeiger weiter setzen. Das hilft dir allerdings nur bei bekannter Zeilenlänge. Mir fällt gerade keine andere Möglichkeit ein, als wirklich Zeile für Zeile einzulesen (fscanf oder gets) und auszuwerten. Buchstabe für Buchstabe ist extrem langsam.
mfg Otis
----------------- A bus station is where busses stop.
A train station is where trains stop.
On my desk there is a workstation...
Never argue with an idiot. They bring you down to their level and beat you with experience.
[ Nachricht wurde editiert von Otis am 22.08.2012 18:51:22 ]
|
Profil
Quote
Link |
milch
Aktiv  Dabei seit: 23.02.2009 Mitteilungen: 296
Aus:
 |     Beitrag No.2, vom Themenstarter, eingetragen 2012-08-22 19:01
|
Zeile für Zeile muss ich ja sowieso Auslesen, aber es stellt sich hier natürlich direkt die Frage ob es wirklich langsamer ist, wenn ich die ersten Zeichen einer Zeile einzeln auslese, denn angenommen der erste Aufruf vonC liefert mir schon das falsche Zeichen dann kann ich direkt zur nächsten Zeile springen, ich prüfe hier ja nur ob dieses Zeichen mit dem ersten Buchstaben meines Suchbegriffes übereinstimmt.
Die alternative wäre mit:C das erste Wort einzulesen, hier muss ich dann mit einer Stringfunktion einen vermutlich deutlich aufwendigeren Vergleich machen. Daher vermute ich das es schneller geht wenn ich zum finden der Zeilen Buchstabenweise einlese. Aber ich lasse mich hier gerne belehren, ich will es ja so schnell wie möglich haben.
Die eigentliche Frage ist nun aber, wie komme ich so schnell wie möglich in die nächste Zeile wenn sich der filepointer in einer Zeile befindet die ich nicht gebrauchen kann?
Wie gesagt die Dateien dich ich untersuchen will können durchaus ein paar 100Megabyte groß sein und davon sind nur vielleicht !20 Zeilen! diejenigen die ich Auswerten will.
|
Profil
Quote
Link |
Otis
Senior  Dabei seit: 06.10.2007 Mitteilungen: 899
Aus: Stralsund
 |     Beitrag No.3, eingetragen 2012-08-22 19:10
|
2012-08-22 19:01 - milch in Beitrag No. 2 schreibt:
Die eigentliche Frage ist nun aber, wie komme ich so schnell wie möglich in die nächste Zeile wenn sich der filepointer in einer Zeile befindet die ich nicht gebrauchen kann?
Ich denke das ist die schnellste Variante, wenn deine Zeilen nicht super lang sind:
Du musst mit fgets die Zeile einlesen, das erste Zeichen deines Buffers untersuchen und dann entsprechend fortfahren:
C const int maxlinelength = 1024;
char mystring [maxlinelength];
fgets(mystring, maxlinelength, pFile);
if(mystring[0] == '#') { // nur Zeilen, die mit # beginnen
// mach was tolles
} |
mfg Otis
----------------- A bus station is where busses stop.
A train station is where trains stop.
On my desk there is a workstation...
Never argue with an idiot. They bring you down to their level and beat you with experience.
[ Nachricht wurde editiert von Otis am 22.08.2012 19:12:11 ]
|
Profil
Quote
Link |
Otis
Senior  Dabei seit: 06.10.2007 Mitteilungen: 899
Aus: Stralsund
 |     Beitrag No.4, eingetragen 2012-08-22 19:27
|
Hmm man könnte vllt. auch mal ausprobieren, ob es evtl. schneller ist einen großen Buffer (vllt. paar KB bis 1MB?) mit einer möglichst einfachen Lesefunktion (also irgendwas ohne Overhead) einzulesen und die Suche nach \n und dem speziellen Zeilenanfang danach selber zu basteln, anstatt zeilenweise zu lesen. Der Aufwand steckt hier ja klar in den Festplattenzugriffen.
Das ist aber nur ne Idee. Es ist aber sicherlich schnell implementiert und einen Test wert.
----------------- A bus station is where busses stop.
A train station is where trains stop.
On my desk there is a workstation...
Never argue with an idiot. They bring you down to their level and beat you with experience.
[ Nachricht wurde editiert von Otis am 22.08.2012 19:30:59 ]
|
Profil
Quote
Link |
milch
Aktiv  Dabei seit: 23.02.2009 Mitteilungen: 296
Aus:
 |     Beitrag No.5, vom Themenstarter, eingetragen 2012-08-22 19:32
|
Hmm die Methode mit fgets finde ich gar nicht mal so schlecht, ich versuche es erstmal damit.
|
Profil
Quote
Link |
Bozzo
Senior  Dabei seit: 11.04.2011 Mitteilungen: 1425
Aus: Franken
 |     Beitrag No.6, eingetragen 2012-08-23 01:13
|
Sehr wahrscheinlich sind die Stringvergleichroutinen schneller, als du das von Hand hinkriegst.
Schreib lieber, was du meinst (also Zeile einlesen und Wort vergleichen), als es selber zu machen. Erstens tust du dich damit leichter beim wiederlesen, zweitens tut sich der Compiler leichter beim optimieren.
Nur wenn das dann immer noch nicht schnell genug ist, und du feststellst, das es wirklich daran liegt, solltest du selbst Hand anlegen.
|
Profil
Quote
Link |
FriedrichLaher
Aktiv  Dabei seit: 30.10.2001 Mitteilungen: 1261
Aus: Oesterr., Wohnort Stuttgart
 |     Beitrag No.7, eingetragen 2012-08-23 07:46
|
@milch
Falls GNU Linux Compiler:
mit dem Formatcode [^\n] bekommst Du die ganze (restliche) Zeile
mit Ausnahme des \n
(um zur nächsten Zeile zu kommen muß das \n dann natürlich überlesen
werden)
----------------- Wenn das Erlernen der Mathematik einigermaßen ihre Erfindung widerspiegeln soll, so muß es einen Platz für Erraten, für plausibles Schließen haben. [Vorw. Georg Pólyas Buch "Mathem. und Plausibles Schliessen, B.1 Induktion und Analogie in d. Mathem."]
[ Nachricht wurde editiert von FriedrichLaher am 23.08.2012 15:33:56 ]
|
Profil
Quote
Link |
viertel
Senior  Dabei seit: 04.03.2003 Mitteilungen: 21565
Aus: Hessen
 |     Beitrag No.8, eingetragen 2012-08-23 08:47
|
@Friedrich
Ich glaube, du verwechselst da was. Was du angibst ist ein regülärer Ausdruck, kein Formatcode.
-----------------

|
Profil
Quote
Link |
gmkwo
Aktiv  Dabei seit: 07.05.2005 Mitteilungen: 476
Aus: Berlin
 |     Beitrag No.9, eingetragen 2012-08-23 08:59
|
Guten Morgen,
in jedem Fall ist es schneller erstmal die gesammte Datei (oder wenigstens große Teile) zu laden.
Wie schon oben erwähnt, gibt es dann sehr schnelle Stringmatching Algorithmen die solltest einsetzten. Wenn du das selbst machen willst, ist eine gute Übung.
Für den Compi sid Zeilenenden nichts anderes als spezielle Zeichen. Das heißt, es wird dir gar nichts anderes übrigbleiben, als den geammten Inhalt anzuschauen wenn du diese finden möchtest.
----------------- In these days the angel of topology and the devil of abstract algebra fight for the soul of every individual discipline of mathematics.. Herman Weyl
|
Profil
Quote
Link |
TheBear
Senior  Dabei seit: 31.01.2006 Mitteilungen: 1222
Aus:
 |     Beitrag No.10, eingetragen 2012-08-23 22:55
|
Moin!
Das Effizienteste und einfachste ist es wahrscheinlich, das Puffern des Streams von der Standardbibliothek übernehmen zu lassen. Dazu ist die Funktion setbuf da. Für das Lesen einer Zeile tut es das erwähnte fgets, und für das Prüfen, ob das Suchwort vorkommt, kannst du strstr oder (wahrscheinlich besser) strncmp nutzen.
Gruß TheBear
----------------- Die “Arbeit” ist ihrem Wesen nach die unfreie, unmenschliche, ungesellschaftliche Tätigkeit.
|
Profil
Quote
Link |
milch
Aktiv  Dabei seit: 23.02.2009 Mitteilungen: 296
Aus:
 |     Beitrag No.11, vom Themenstarter, eingetragen 2012-08-24 03:11
|
Und der Vorteil des Pufferns mit setbuf ist der das die Einlesefunktionen dann schneller arbeiten?
Ich überlege gerade, dass ich für das Verarbeiten mit Stringfunktionen ja sowieso auf eigene Substrings zurückgreifen muss oder anders gesagt würde sich mein Programm nicht verändern nachdem ich mit fgets etc die Daten eingelesen habe. Oder soll ich hier direkt mit dem Puffer arbeiten? Wenn ich das nämlich richtig verstehe kann ich nach der Verwendung von setbuf ganz normal mit dem filepointer arbeiten (und nicht selbst mit dem Puffer arbeiten).
|
Profil
Quote
Link |