Die Mathe-Redaktion - 22.05.2013 11:41
Auswahl
Aktion im Forum
Suche
Stichwortsuche in Artikeln und Links von Matheplanet
Suchen im Forum
Suchtipps

Bücher
Englische Bücher
Software
Suchbegriffe:
Mathematik bei amazon
Naturwissenschaft & Technik
In Partnerschaft mit Amazon.de
Kontakt
Mail an Matroid
[Keine Übungsaufgaben!]

Impressum

Bitte beachten Sie unsere Nutzungsbedingungen, die Distanzierung, unsere Datenschutzerklärung und
die Forumregeln.

Sie können Mitglied werden oder den Newsletter bestellen.

Der Newsletter April 2013

Für Mitglieder
Mathematisch für Anfänger
Wer ist Online
Aktuell sind 824 Gäste und 27 Mitglieder online.

Sie können Mitglied werden:
Klick hier.

Über Matheplanet
 
Zum letzten Themenfilter: Themenfilter:
Matroids Matheplanet Forum Index
Moderiert von matph
Informatik » Programmiersprachen » C: Dateizeiger an den Anfang der nächsten Zeile verschieben?
Druckversion
Druckversion
Autor
Universität/Hochschule J C: Dateizeiger an den Anfang der nächsten Zeile verschieben?
milch
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.02.2009
Mitteilungen: 296
Aus:
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
Otis
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 06.10.2007
Mitteilungen: 899
Aus: Stralsund
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
milch
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.02.2009
Mitteilungen: 296
Aus:
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 von
C
fscanf(fp,"%c",&c);
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
fscanf(fp,"%s",string);
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 auf diesen Beitrag Link
Otis
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 06.10.2007
Mitteilungen: 899
Aus: Stralsund
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
Otis
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 06.10.2007
Mitteilungen: 899
Aus: Stralsund
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
milch
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.02.2009
Mitteilungen: 296
Aus:
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
Bozzo
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 11.04.2011
Mitteilungen: 1425
Aus: Franken
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
FriedrichLaher
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 30.10.2001
Mitteilungen: 1261
Aus: Oesterr., Wohnort Stuttgart
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
viertel
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 04.03.2003
Mitteilungen: 21565
Aus: Hessen
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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.


-----------------
Bild



  Profil  Quote  Link auf diesen Beitrag Link
gmkwo
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 07.05.2005
Mitteilungen: 476
Aus: Berlin
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
TheBear
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 31.01.2006
Mitteilungen: 1222
Aus:
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
milch
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.02.2009
Mitteilungen: 296
Aus:
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  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 auf diesen Beitrag Link
milch hat die Antworten auf ihre/seine Frage gesehen.
milch hat selbst das Ok-Häkchen gesetzt.
Bewerte diesen Thread:
[Was sonst bewertet wurde]
 Neues Thema [Neues Thema]

 Druckversion [Druckversion]


Wechsel in ein anderes Forum:
 Suchen    
 
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2013 by Matroids Matheplanet
This web site was made with PHP-Nuke, a web portal system written in PHP. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen.
Lesen Sie die Nutzungsbedingungen, die Distanzierung, die Datenschutzerklärung und das Impressum.
[Seitenanfang]