Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Tiedostossa rivien kääntely

Sivun loppuun

doze [10.09.2004 04:31:59]

#

Tämä on luultavasti todella helppokin tehdä, mutta kun ei ajatus tunnu luistavan, joten apua kaivataan.

Minulla on tiedosto jossa tietoja tässä muodossa

abcd|efgh|jklm|opqr|
ebbe|iiaa|klsk|iooi|


Ja minulla on myös skripti joilla voin listata tiedoston tiedot, sekä valita yhden rivin palautettavaksi funktiolle. Nyt pitäisi vain saada aikaan sellainen funktio, joka käy tiedoston läpi ja kirjoittaa uuden vaihtamalla valitun rivin yhden ylöspäin tai yhden alaspäin.

Olen ajatellut riviä alaspäin siirtävää systeemiä näin:

<?php
$tiedosto = joku.txt;
$data = file($tiedosto);
$tiedot = array();

// kerätään tiedoston ekat "tunniste" solujen tiedot
for ($i=0; $i<count($data); $i++) {
	$solu = explode("|", $data[$i]);
	$tiedot[$i] = $solu[0];
}

// järjestettävän rivin tunniste solu
$eka_solu = $_POST["eka_solu"];

// tarkastetaan onko järjestettävää riviä tiedostossa
if (in_array($eka_solu, $tiedot) == TRUE) {

	$solu = explode("|", $data[array_search($eka_solu, $tiedot)]);
	$temp = "".$tiedosto.".temp";
	$temptiedosto = fopen($temp,"w+");
	for ($i=0; $i<count($data); $i++) {
		$rivi = $solu[0]."|".$solu[1]."|".$solu[2]."|".$solu[3]."|\n";
		if($solu[0] == $eka_solu) {

			niin laita muistiin tämä rivi ja kirjota seuraava rivi ja sitten muistista tämä rivi?

		} else {
			fwrite($temptiedosto,$rivi);
		}
	}
	fclose($temptiedosto);
	unlink($tiedosto);
	rename($temp,$tiedosto);
}
?>

Olenko ihan hakoteillä? onko täällä esimerkkiä missään tämän kaltaisesta systeemistä..?

En hirveästi tiedä PHP:n erikoisuuksista, joten tähän voipi olla jokin yksinkertainenkin konsti..

makeuu [10.09.2004 08:11:25]

#

$data = file($tiedosto);
$tiedot = array();

eikö tuo file funktio ota tiedoston valmiiksi arrayhyn?

tsuriga [10.09.2004 11:10:15]

#

Pitäsköhän tuossa olla: $tiedosto = "joku.txt";
makeuu kyllä, mutta huomaat varmaan itsekin asioita asiattomia :).

$temp = "".$tiedosto.".temp";

Ei kai sinne alkuun tarvitse lisätä tyhjää ("")?
Itse tekisin ehkä niin, että looppaisin tiedoston rivien läpi ja muodostaisin uuden taulukon, jonka kirjoittaisin sitten tiedostoon merkkijonona. Näin alaspäin siirtäminen on helpompaa (jos teet noin niin rivi on jo tiedostossa ja sen taakse siirtäminen on hankalampaa kuin jos rivi olisi taulukon edellisessä indeksissä). Oletkos kokeillut tuota tapaa käytännössä? Kyllä sen pitäisi toimia :). Rivin alaspäin (pienempään indeksiin) siirtämisessä voit käyttää vaikka jotain väliaikaismuuttujaa.

Olga [10.09.2004 14:06:16]

#

makeuu:

$data <-- taulukko johon file-funktion palauttama array laitetaan.
$tiedot <-- uusi taulukko tulevia toimia varten

doze [10.09.2004 20:40:03]

#

Voisiko joku antaa hieman koodi esimerkkiä, kun ei tuo itseltä taivu.. Entäs sitten rivin siirtäminen yhden ylöspäin? tuo aloittamani tapa ei sovellu taas siihen ollenkaan. Mitens tämä sitten menisi:

lainaus:

Itse tekisin ehkä niin, että looppaisin tiedoston rivien läpi ja muodostaisin uuden taulukon, jonka kirjoittaisin sitten tiedostoon merkkijonona. Näin alaspäin siirtäminen on helpompaa

Onnistuuko tuolla tavalla helpommin myös se yhden ylöspäin siirtäminen? ...tosiaan, jos koodia hieman saisi, ei tarvitse valmiiksi asti tehdä mutta hieman apua edes :)

ZcMander [10.09.2004 21:18:07]

#

Öö, en ymmärtänyt kysymystä, array käännetään array_reverse($taalukko);

doze [10.09.2004 21:40:21]

#

Ei koko taulukkoa olla kääntämässä.. vain tarkoituksena olisi saada tekstitiedostossa vaihdettua yksi (valittu) rivi tiedostosta yhden rivin ylöspäin tai yhden alaspäin..

tsuriga [10.09.2004 22:02:12]

#

Onnistuuhan se helpommin, koska muuten joudut taas lukemaan tiedoston uudestaan jos olet jo kirjoittanut edellisen rivin tiedostoon. Taulukossa ylöspäin(/taaksepäin) siirtäminen hoituu roundabout näin:

<?php
if ($rivi == $taaksepainsiirrettavarivi) {
  $valiaikaismuuttuja = $taulukko[$indeksinyt-1];
  $taulukko[$indeksinyt-1] = $taulukko[$i];
  $taulukko[$indeksinyt] = $valiaikaismuuttuja;
?>

PHP:ssä tähän voi olla myös yhdellä rivillä hoituva operaatio, mutta en siitä tiedä enempää, tuskin se nopeuden kannalta on niin tärkeää. Tuosta puuttuu vielä tarkistus, jos rivi on ensimmäinen, ei sitä tietenkään voi siirtää taaksepäin. Sama toisessa operaatiossa, eli ylintä ei voi siirtää eteenpäin.

doze [11.09.2004 00:17:45]

#

En tiedä teinkö sen nyt niin kuin tarkoitit, mutta tein nyt rivin ylöspäin siirtämisen näin ja toimii ok, vielä täytyy tehdä checkit että ollaanko ensimmäisen rivin kohdalla. Mutta kiitokset avusta jo tässä vaiheessa! :)

<?php
$tiedosto = joku.txt;
$data = file($tiedosto);
$tiedot = array();

// kerätään tiedoston ekat "tunniste" solujen tiedot
for ($i=0; $i<count($data); $i++) {
    $solu = explode("|", $data[$i]);
    $tiedot[$i] = $solu[0];
}

// järjestettävän rivin tunniste solu
$eka_solu = $_POST["eka_solu"];

// tarkastetaan onko järjestettävää riviä tiedostossa
if (in_array($eka_solu, $tiedot) == TRUE) {

    $temp = "".$tiedosto.".temp";
    $temptiedosto = fopen($temp,"w+");
	$uusitaulu = array();
	for ($i=0; $i<count($data); $i++) {
		$solu = explode("|", $data[$i]);
		if($entry[0] != $eka_solu) {
			$uusitaulu[$i] = $data[$i];
		} else {
			$valiaikaismuuttuja = $data[$i-1];
			$uusitaulu[$i-1] = $data[$i];
			$uusitaulu[$i] = $valiaikaismuuttuja;
		}
	}
	for ($i=0; $i<count($uusitaulu); $i++) {
		fwrite($temptiedosto,$uusitaulu[$i]);
	}
    fclose($temptiedosto);
    unlink($tiedosto);
    rename($temp,$tiedosto);
}
?>

Niin ja alaspäin rivin siirtäminen periaattees sama positiivisilla lisäyksillä mutta kasvatetaan vielä indexiä pyöräyttämisen jälkeen.. näin:

<?php
$tiedosto = joku.txt;
$data = file($tiedosto);
$tiedot = array();

// kerätään tiedoston ekat "tunniste" solujen tiedot
for ($i=0; $i<count($data); $i++) {
    $solu = explode("|", $data[$i]);
    $tiedot[$i] = $solu[0];
}

// järjestettävän rivin tunniste solu
$eka_solu = $_POST["eka_solu"];

// tarkastetaan onko järjestettävää riviä tiedostossa
if (in_array($eka_solu, $tiedot) == TRUE) {

    $temp = "".$tiedosto.".temp";
    $temptiedosto = fopen($temp,"w+");
	$uusitaulu = array();
	for ($i=0; $i<count($data); $i++) {
		$solu = explode("|", $data[$i]);
		if($entry[0] != $eka_solu) {
			$uusitaulu[$i] = $data[$i];
		} else {
			$valiaikaismuuttuja = $data[$i+1];
			$uusitaulu[$i+1] = $data[$i];
			$uusitaulu[$i] = $valiaikaismuuttuja;
			$i++;
		}
	}
	for ($i=0; $i<count($uusitaulu); $i++) {
		fwrite($temptiedosto,$uusitaulu[$i]);
	}
    fclose($temptiedosto);
    unlink($tiedosto);
    rename($temp,$tiedosto);
}
?>

tsuriga [11.09.2004 02:08:40]

#

    for ($i=0; $i<count($uusitaulu); $i++) {
        fwrite($temptiedosto,$uusitaulu[$i]);
    }

Kannattaa tehdä ehkä näin:

fwrite($temptiedosto,implode("",$uusitaulu));

Silloin kirjoituksella on vain yksi mahdollisuus epäonnistua (oletan, että fwrite olisi herkempi epäonnistumaan kuin implode, tämähän ei ole faktatietoa vaan mutu-) ja onhan tuo one-lineri :).

Koko arrayta ei tarvitse käydä läpi noin, array_search on tutustumisen arvoinen funktio. Eli teet muutokset vain suoraan siihen file-funktion palauttamaan taulukkoon (tässä tapauksessa $data).

$tiedosto = joku.txt; <-- tuo näyttää edelleenkin hassulta, merkkijonon ympärille kuuluisi "":t.
$temp = "".$tiedosto.".temp"; <-- tässä ne "":t ovat taas turhat tuolla alussa

doze [11.09.2004 05:34:49]

#

lainaus:

$tiedosto = joku.txt; <-- tuo näyttää edelleenkin hassulta, merkkijonon ympärille kuuluisi "":t.
$temp = "".$tiedosto.".temp"; <-- tässä ne "":t ovat taas turhat tuolla alussa

Joo noi parit kohdat on vähän tollain siellä.. kun periaatteessa toi koko juttu on paljon monimutkaisempi mutta kirjotin sen uusiks yksinkertaistetuksi, ettei ala tänne kilometri spämmejä pastettaan.. kukaan ei olis kuitenkaan jaksanu lukea sitä koodia sitten :) ..mutta tosiaan, tuli sitten hieman kirjotusvirheitä siinä.. ja kun muuttujien nimiä vaihtelin selkeimmiksi, niin toivottavasti huomasin ne edes vaihtaa joka kohdassa :)

lainaus:

fwrite($temptiedosto,implode("",$uusitaulu));

Aih, toihan onkin paljon kätsympi noin.. eipä ole tullut tuota implodeakaan tutkailtua.. :)

lainaus:

Koko arrayta ei tarvitse käydä läpi noin, array_search on tutustumisen arvoinen funktio. Eli teet muutokset vain suoraan siihen file-funktion palauttamaan taulukkoon (tässä tapauksessa $data).

Hmm.. joo, täytyy tutkailla.. toistaiseksi tämä kelpaa tälläisenään, mutta tuollainen array_search olisi varmasti kevyempi skripta.. tuota array_searchia voisi näköjään käyttää kätevästi noissa minun tietojen päivitys skriptoissakin, mitä esim https://www.ohjelmointiputka.net/keskustelu/6318-filujen-rivit tuonne rustailin (en saanut tehtyä kunnon linkkiä tuosta, eikä ohjeissakaan ollut ohjeita siitä).. päivittämisessä olen käyttänyt myös tälläistä systeemiä missä käydään taulukko for-lauseella läpi ja kirjoitetaan vain muokattavan rivin kohdalla uudet tiedot..

tsuriga [11.09.2004 13:50:44]

#

EDIT:
Tällaisenaan tätä ei ole kovin hyvä vielä käyttää lopussa ilmoitettujen bugien(loogisten ajatusvirheiden) takia. Joitakin periaatteita voi tietenkin soveltaa.

Saatanpa itsekin moista tarvita ja nyt kun tuota innostuin säätämään niin laitanpa tähän koodia:

<?php
/* Tiedoston rivin siirto alas- tai ylöspäin */

$tiedosto = "joku.txt";
$data = file($tiedosto);
$tiedot = array();

// käydään tiedot läpi ja haetaan indeksit
foreach($data as $rivi) $tiedot[] = substr($rivi,0,strpos($rivi,"|"));

$solu = $_GET['solu'];	// järjestettävän rivin tunnistesolu
$suunta = $_GET['suunta'];		// rivin siirtosuunta

// jos järjestettävä rivi löytyy tiedostosta
if (in_array($solu, $tiedot) == TRUE) {
  $i = array_search($solu, $tiedot);	// etsityn tunnisteen indeksi taulukossa
// siirretään tunnisteen sisältävä rivi haluttuun suuntaan
  $suunta ? list($data[$i], $data[$i-1]) = array($data[$i-1], $data[$i]) : list($data[$i+1], $data[$i]) = array($data[$i], $data[$i+1]);
// kirjoitetaan tulos tiedostoon
  $tt = fopen($tiedosto,"w+");
  fwrite($tt,implode("",$data));
  fclose($tt);
  }

?>

Tunnettuja ongelmia:

Tuo on huomattavasti nopeampi jo yhdellä loopilla. Tuosta puuttuu tarkistus jos indeksi on nolla. Pitää vielä kehitellä jos jaksaa, nyt aamupalalle :)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta