PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeilenweise in Datei schreiben?



tybalt0125
13-08-2005, 09:33
Hi,

jetzt habe ich mir vorgenommen einen kleinen Counter zu schreiben.
Ich möchte jetzt die einzelnen Counterstände in eine Textdatei schreiben und zwar
für jeden einzelnen Counter eine neue Zeile.
Allerdings funktioniert das nicht, denn er schreibt immer alles in eine Zeile.



for( $i = 0 ; $i < 3 ; $i++ ){
fputs( $fp , "$counter[$i]" , strlen( $counter[$i] ) );
}


Was mache ich falsch?

michael.sprick
13-08-2005, 09:45
Du machst ja auch keinen Zeilenumbruch...



fputs( $fp , "$counter[$i]" , strlen( $counter[$i] ) );


vs.



fputs( $fp , "$counter[$i]\n" , strlen( $counter[$i] ) );

tybalt0125
13-08-2005, 10:04
Du machst ja auch keinen Zeilenumbruch...



fputs( $fp , "$counter[$i]" , strlen( $counter[$i] ) );


vs.



fputs( $fp , "$counter[$i]\n" , strlen( $counter[$i] ) );

Das habe ich aber auch schon probiert und es hat nicht geklappt. :(
Verstehe ich nicht, wieso klappt das denn nicht?

Pingu
13-08-2005, 10:25
Du machst ja auch keinen Zeilenumbruch...



fputs( $fp , "$counter[$i]" , strlen( $counter[$i] ) );


vs.



fputs( $fp , "$counter[$i]\n" , strlen( $counter[$i] ) );

Da fehlt die Längenangabe. Dadurch fällt das "\n" hinten herunter.

Pingu

tybalt0125
13-08-2005, 10:30
Welche Längenangabe?
Damit puts weiss, wei lang der String ist?
Das mache ich doch mit dem strlen. Oder habe ich Dich jetzt falsch verstanden?

edit:
jetzt habe ich verstanden... :)
Aber:


for( $i = 0 ; $i < 3 ; $i++ ){
$counter[$i] = $counter[$i]."\n";
fputs( $fp , "$counter[$i]" , strlen( $counter[$i] ) );
}

So, macht er mir aber immer mehr "\n" da rein, so das ich später viele leere Zeilen habe.
Wenn ich das so mache:


fputs( $fp , "$counter[$i]\n" , strlen( $counter[$i]."\n" ) );

müsste er ja auch diese leerzeilen machen. Wie kann ich das verhindern?

tybalt0125
13-08-2005, 11:13
Wenn ich die Datei schon fertig vorliegen habe, dann sieht die so aus:

4
6
7
Wenn ich dann die Zeilen einlese, mit fgets und die dann nachher wieder speichere mit

for( $i = 0 ; $i < 3 ; $i++ ){
fputs( $fp , "$counter[$i]" , strlen( $counter[$i] ) );
}
dann geht das...

Was mache ich denn falsch?

BlueJay
13-08-2005, 11:26
Saugst du gleich eine ganze Zeile in den Puffer, oder schlürfst du die Datei via file ein, hast du den/die Zeilenumbruch/brüche hinten dran.

Schreibst du die Zeile "unbehandelt" wieder zurück, ist alles ok.

Zum Verarbeiten musst du das Zeilenende abknabbern, dann die Daten ändern, dann wieder das Zeilenende anhängen und wegschreiben.

so long,
BlueJay

tybalt0125
13-08-2005, 11:36
Saugst du gleich eine ganze Zeile in den Puffer, oder schlürfst du die Datei via file ein, hast du den/die Zeilenumbruch/brüche hinten dran.

Schreibst du die Zeile "unbehandelt" wieder zurück, ist alles ok.

Zum Verarbeiten musst du das Zeilenende abknabbern, dann die Daten ändern, dann wieder das Zeilenende anhängen und wegschreiben.

so long,
BlueJay
Könntest Du das etwas genauer beschreiben, ich bin noch ein ziemlicher Neuling in PHP.

So, jetzt mal der ganze code...
Dies ist der Code, mit dem ich die Daten auslese:


if(!file_exists($counterfile) ){
$counter[0] = $counter[1] = $counter[2] = 0;
} else {
$fp = fopen($counterfile,"r");
$i = 0;
while($data = fgets($fp,1000) ){
$counter[$i] = $data;
$i++;
}
fclose($fp);
}

Und mit diesem Code schreibe ich die Daten wieder in die Datei.


for( $i = 0 ; $i < 3 ; $i++ ){
fputs( $fp , "$counter[$i]" , strlen( $counter[$i] ) );
}

BlueJay
13-08-2005, 17:57
$fp = fopen($counterfile,"r");
$i = 0;
while($data = fgets($fp,1000) ){
$counter[$i] = $data;
$i++;
}
fclose($fp);


Wenn die Zahlendarstellungen nicht zu üppig sind, gibt es die Werte mit Zeilenumbruch.

Der geht beim Bearbeiten wahrscheinlich verloren, da eine automatische Typenumwandlung passiert.

Also:
ungeänderte Daten:
fputs($fp,$counter[$i],strlen($counter[$i]));

geänderte Daten:
$zeile=$counter[$i]."\n";
fputs($fp,$zeile,strlen($zeile));

Alternative beim Einlesen: (von mir bevorzugt)
$counter[$i]=trim($data);
// knabbert Zeilenumbrüche, Leerzeichen und sonstigen Mist vorne und hinten ab

Da hast du geklärte Verhältnisse, bei denen du beim Schreiben immer einen Zeilenumbruch einfügen musst.

so long,
BlueJay

tybalt0125
13-08-2005, 19:12
Du meinst also ich sollte meine Daten ganz normal einlesen und die dann mit dem Befehl trim() trimmen?
Um danach dann immer mit einem \n die Daten in die Datei zurückschreiben?

Naja, ich werde das morgen mal ausprobieren.

Vielleicht hat ja noch jemand eine andere Lösung... :)

tybalt0125
15-08-2005, 08:52
Das funktioniert, allerdings finde ich das nicht gerade gelungen, geht das nicht irgendwie anders?
Sonst hat keiner eine Idee?

quinte17
15-08-2005, 08:59
hast du des mit den leerzeilen schon gelöst?
wenn nein hier beispielcode:


$zeile[] = "bla";
$zeile[] = "";
$zeile[] = "bla";

for($i=0;$i<3;$i++)
{
if($zeile[$i])
{
printf($zeile[$i]."\n");
}
}

somit werden nur die zeilen geschrieben, die auch etwas enthalten.

warum verwendest du kein fprintf/fscanf?

greetz

tybalt0125
15-08-2005, 09:27
Ich verwende das nicht, weil ich nicht wusste, das es das auch für php gibt... :)
Jetzt bin ich wieder etwas schlauer... :)
Danke

michael.sprick
15-08-2005, 10:01
hast du des mit den leerzeilen schon gelöst?
wenn nein hier beispielcode:


$zeile[] = "bla";
$zeile[] = "";
$zeile[] = "bla";

for($i=0;$i<3;$i++)
{
if($zeile[$i])
{
printf($zeile[$i]."\n");
}
}

somit werden nur die zeilen geschrieben, die auch etwas enthalten.

warum verwendest du kein fprintf/fscanf?

greetz


neenee - das Problem liegt ja ganz woanders.

Wenn er einfach eine Variable ($var=5) in die Datei schreibt, dann muss er ein \n mit anhängen da sonst die nächste Zahl in der gleichen Zeile landet.

Wenn er aber erst aus einer Datei eine Zeile ausliest, dann steht am Ende dieser Zeile bereits ein \n. Durch das zurückschreiben der Zahl und das anhängen eines weiteren \n ensteht die Leerzeile... es gibt also in dem Sinne keine leeren Array Elemente, sondern nur doppelte Zeilenumbrüche.

Er muss nach dem einlesen der Zählerstände erst alle \n entfernen - das geht z.B. mit trim.

Also: Grundsätzlich alle Zählerstände trim()-en und beim Zurückschreiben IMMER den Zählerstand + \n schreiben.

tybalt0125
15-08-2005, 10:37
Ja, so habe ich es jetzt auch gemacht. Funktioniert auch ganz gut... Danke für Deine Hilfe.
Ich hatte bloß gehofft, das es noch eine elegantere Lösung gibt. :)

Danke

quinte17
15-08-2005, 13:05
? warum sind da noch zeilenumbrüche ?
also wenn ich des mit fscanf lese:


<?php
$fp = fopen("bla.txt","r+b");

while(fscanf($fp,"%d",$zahl))
{
printf("%d<br>",$zahl);
}

fclose($fp);
?>

wobei in bla.txt folgendes drinsteht


123
1234
1245

bekomme ich folgenden output:


123<br>1234<br>1245<br>

warum ist des also so schwierig? und was ist dann an meinem vorigen post so falsch? ich verstehe euch da nicht.

greetz

michael.sprick
15-08-2005, 14:08
an fscanf ist nix falsch - das geht so...

aber die Abfrage, ob ein Arrayelement leer ist hilft nicht.
Du hast die Abfrage gemacht, um Leerzeilen in der neu geschriebenen Datei zu vermeiden.

die Leerzeilen entstehen aber nicht durch leere Array Elemente, sondern eben durch den Zeilenumbruch, der noch im String vorhanden ist, wenn er das Ganze per fgets() einliest. Das meinte ich...

quinte17
15-08-2005, 14:46
deshalb fragte ich ihn ja warum er des nicht mit fscanf macht, da hat man solche probleme nicht und ist viel einfacher und verständlicher für sowas.

tybalt0125
16-08-2005, 08:00
deshalb fragte ich ihn ja warum er des nicht mit fscanf macht, da hat man solche probleme nicht und ist viel einfacher und verständlicher für sowas.

ich habe jetzt einfach mal fgets genutzt, weil ich nicht wusste, das es scanf auch gibt. Das nächste mal werde ich scanf benutzen.
Danke für den Hinweis.

Ich habe es jetzt auch schon hinbekommen. Danke