Moro taas.
Jos on $string, jonka arvo on "Pekalla on huomenna poutasää". Sitten käyn sen sanan merkit yksi kerrallaan läpi (for). Sitten on tuo strpos() funktio:
<?php $string = "Pekalla on huomenna poutasää"; $haettava = $_GET["hae"]; for($i = 0; $i < strlen($string); $i++) { $strpos = strpos($haettava, $string[$i]; //... } ?>
Nyt tuolla for käydä läpi, että montako arvausta on väärin (Eli jos on arvattu p, e, k, a, l, o, x esimerkiksi), niin pitäisi laskea että miten monta on arvauksissa väärin. Jos laitan vaan, että $vaarin = 0; if($strpos == false) $vaarin++;, niin se ei toimi. Ainakaan ei minulla.
Elikkä, jos merkkiä ei löydy $string muuttujasta, niin lisätään $vaarin muuttujan arvoa yhdeltä. Eli oikeastaan näin:
<?php $sana = "Pekalla on uusi auto."; $arvaukset = $_GET["arvaukset"]; $vaarin = 0; for($i = 0; $i < strlen($sana); $i++) { $strpos = strpos($arvaukset, $sana[$i]); if($strpos == false) $vaarin++; else continue; } echo $vaarin; ?>
Tuossa vaan on ongelma: Tuo laskee tyhjänkin merkinnän vääräksi, eli jos $_GET["hae"] taulukko on tyhjä, niin on tuon mukaan 21 väärää vastausta.
Toivottavasti hoksaatte mitä haen.
Ei toimi noin. Jos laittaa "?arvaukset=p", niin tulos on heti 21.
MIB kirjoitti:
Ei toimi noin. Jos laittaa "?arvaukset=p", niin tulos on heti 21.
Niin, eikö tässä juuri siitä ollut kyse? Eihän tuosta kyseisestä merkkijonosta p:tä löydy, P löytyy kylläkin.
Oma logiikkasi on nyt virheellinen. Yrität tarkistaa, mitä merkkejä puuttuu, vaikka pitäisi tarkistaa, mitkä ovat ylimääräisiä. Lisäksi 0 == false, joten et tunnista ensimmäistä merkkiä oikein, koska strpos palauttaa arvon 0. Oikea vertailu on ===. Myös isot ja pienet kirjaimet menevät nyt väärin, joten käytä strtolower-funktiota (tai strtoupper) sekä arvauksiin että arvattavaan.
No, tämä ei silti tee kokonaan haluttua.
Koitas itse. Se ei saisi palauttaa getillä ?arvaukset=P yhtään mitään. Eli, se laskisi väärät vastaukset vain niistä jotka on tuolla get muuttujassa.
?arvaukset=P, tulos 0
?arvaukset=p, tulos 1
?arvaukset=xyz, tulos 3
Edit. Juuri niin Metabolix, tuota tarkoitin. Ei tullut vaan tuota ylimääräinen sanaa mieleen. Kerrotko miten pitäisi muakata tota?
Vaihda $string ja $haettava toisin päin ja tee muut mainitsemani muutokset (vertailuoperaattori ja strtolower). Ja käytä PHP:n manuaalia, ennen kuin kysyt uudestaan, nimittäin siellä selitetään nämäkin kaksi asiaa.
Missä kohdin vaihdan $stringin ja $haettavan toisin päin?
No siinä tarkistuksessa. Nythän katsot, mitkä $stringin ovat $haettavassa, kun pitäisi katsoa, mitkä $haettavan merkit ovat $stringissä.
En ymmärtänyt oikein, voitko näyttää?
Nyt käyt merkki kerrallaan läpi merkkijonoa "Pekalla on uusi auto." ja tutkit löytyykö sen merkkejä arvauksestasi.
Tarkoituksenasi kaiketi oli käydä läpi arvausta merkki kerrallaan ja tutkia löytyykö niitä merkkijonosta.
En vieläkään ymmärtänyt, että mitä pitäisi muuttaa. Siis, ainoa kohta mihin voisin kuvitella sen saavani, on tuo strpos(), mutta sitten siinä taas ei ole mitään järkeä jos P kirjaimesta etsitään "Pekalla on uusi auto." -tekstiä.
Käy for-silmukassa läpi arvauksen merkkejä, älä arvattavan merkkijonon?
Voisitko antaa esimerkin? :/
Valmista koodia en anna, koska et näytä yhtään halukkuutta miettiäksesi asiaa itse, vaikka virhekohtaa on sinulle selitetty.
Aloitusviestissäsi selität omaa tai jonkun muun sinulle tekemää koodia väärin. Sanot "jos merkkiä ei löydy $string muuttujasta", vaikka koodi ei etsi merkkiä $string-muuttujasta, vaan $haettavasta. Käyt for-silmukassa läpi väärää merkkijonoa ja etsit sen merkkejä väärästä merkkijonosta.
Tässä yksi "korjaus", tosin enemmänkin tässä rikotaan koodia vielä toisestakin kohti niin, että se näyttää lopulta toimivan oikein:
<?php $sana = $_GET["hae"]; $haettava = "Pekalla on huomenna poutasää";
Mieti sitä sitten. Olen asiasta aivan samaa mieltä kuin Chiman: tässä on jo selityksiä varmaan kymmenen vastaavan ongelman tarpeiksi, ja silti et tunnu millään tajuavan. Oletko edes yrittänyt korjata asiaa mitenkään? Miten? Mikä oli lopputulos? Mikä tässä esitetyissä neuvoissa ("vaihda kaksi muuttujaa silmukasta") on hankala ymmärtää?
No, sain sen sitten toimimaan.
<?php $sana = $_GET["sana"]; $lause = "Pekalla on uusi auto."; $vaarat = 0; $merkit = ""; echo "Väärät ennen for-silmukkaa: " . $vaarat . "<br>"; for($i = 0; $i < strlen($sana); $i++) { $pos = strpos($lause, $sana[$i]); if($pos === false) { $vaarat++; $merkit .= $sana[$i]; } } echo "Väärä merkkien summa: " . $vaarat . "<br>"; echo "Väärät merkit: $merkit"; ?>
Ehkä sen voisi tehdä vähän helpomminkin (?), mutta noin nyt aluksi. Kiitos teille avusta.
Toivottavasti nyt jälkikäteen käsität, että olet tehnyt tuossa juuri sen muutoksen, jota tässä on pitkän aikaa yritetty selittää, eli olet vaihtanut for-silmukan käymään läpi eri muuttujaa, ja olet vaihtanut strpos-funktion parametrit vastaavasti oikein. Aluksihan hait sanasta lauseen merkkejä, nyt haet lauseesta sanan merkkejä.
Kyllä ymmärsin.
Huomasin tässä, että tuo ei nähtävästi osaa ääkkösiä käyttää oikein.
<?php for($a = 0; $a < strlen($aakkoset); $a++) { $strpos2 = strpos($arvaukset, $aakkoset[$a]); if($strpos2 === false) { //Tulostetaan arvauslinkit echo "<a href=\"hirsipuu.php?a=" . $_GET["a"] . $aakkoset[$a] . "\">" . $aakkoset[$a] . "</a> "; } else echo "<strike>" . $aakkoset[$a] . "</strike> "; ] ?>
Tuon pitäisi siis yliviivata kaikki merkit, jotka on arvattu. Tämä ei vain yliviivaa ääkkösiä. Eli, tuo strpos() ei nähtävästi osaa käsitellä ääkkösiä?
Esimerkki: ?kirjaimet=abcäöå
Tulostus: <strike>a</strike> <strike>b</strike> <strike>c</strike> ä ö å
Vaikka tulostuksen kuuluisi olla: <strike>a</strike> <strike>b</strike> <strike>c</strike> <strike>ä</strike> <strike>ö</strike> <strike>å</strike>
Jos käytät UTF-8-merkistöä, ääkköset vievät kaksi tavua. PHP on tyhmästi suunniteltu yksitavuisille merkistöille, ja UTF-8:n käyttö edes jossain määrin oikein vaatii mbstring-laajennoksen, ja merkkien hakuun pitää hakasulkujen sijaan käyttää substr-funktiota. Voit myös muuttaa merkit tarkistuksen ajaksi toiseen merkistöön iconv-funktiolla (vaatii iconv-laajennoksen), tai voit vaihtaa ääkköset str_replacella muiksi merkeiksi (%, $, @ jne; valitse tavallisia ASCII-merkkejä, joita tekstissä ei muuten esiinny).
Kyllä käytän UTF-8 merkistöä. Minulla pitäisi olla kyllä käytössä mbstring ja iconv laajennukset.
Metabolix kirjoitti:
merkkien hakuun pitää hakasulkujen sijaan käyttää substr-funktiota.
Anteeksi miten? En oikein hoksannut, että mitkä hakasulkeet pitää poistaa ja laittaa substr-funktio.
Koitin korvata ääkköset erikoismerkeiksi ja palauttaa takaisin, mutta ei toiminut. Jos ette ole vielä keksineet, että mitä tästä voisi tulla, niin sanon että hirsipuu-peli.
Muuten, miten saisin tuon kelpuuttamaan kaikenkokoiset kirjaimet? IF-lauseella varmaankin, mutta nyt ei raksuta. Täytyy koulupäivän aikana miettiä lisää.
Usein kirjainkoosta riippumattomuus toteutetaan muuttamalla käyttäjän syöte esimerkiksi isoiksi kirjaimiksi (esim. strtoupper) ja koodaamalla tarkistukset pelkille isoille kirjaimille. Tällöin homma toimii, antoi käyttäjä sitten pieniä tai isoja kirjaimia.
Nojuu, kyllähän se sillain on järkevintä. No, nyt muutin kaikki isoiksi kirjaimiksi. Vielä kun saan ääkköset kuntoon :D
Mene sivulle hirsipuu.php?a=ä ja tulosta seuraavat:
<?php $q = explode("=", $_SERVER['QUERY_STRING']); echo "<p>", end($q), "</p>"; echo "<p>", urlencode($_GET['a']), "</p>"; echo "<p>", urlencode('ä'), "</p>";
Ensimmäisestä pitäisi selvitä varmasti, missä merkistössä selain lähettää tekstin. Toisen pitäisi olla sama, ellei PHP tee jotain mystistä muunnosta välissä. Kolmas kertoo, missä merkistössä varsinainen PHP-koodisi on, ja jos tämä poikkeaa edellisestä, olet mokannut sivujesi merkistöjen kanssa pahan kerran.
Tuota strtoupper-muunnosta ehdotin jo kauan sitten. Lisäksi kannattaa pitää mielessä, että se ei välttämättä osaa muuttaa ääkkösiä.
ä %E4 %C3%A4
En usko että tuo on se mitä kuuluu, vai olenko väärässä?
Kuten näet, GET-muuttuja on ISO-8859-1-enkoodattu mutta PHP:n 'ä' on UTF-8-enkoodattu. (Ensimmäisessä kohdassa selain ei toiminutkaan aivan odotetusti, mutta tällä ei nyt ole merkitystä, koska vika selvisi kahdesta jälkimmäisestä.)
Lähetätkö sivujesi mukana tiedon oikeasta merkistöstä? Jos katsot esimerkiksi Firefoxin Live HTTP Headers -lisäosalla HTTP-otsikoita, mitä Content-Type-otsikossa lukee?
Voit lähettää oikean sisältötyypin header-funktiolla:
<?php // "text/html" tarkoittaa HTML:ää tai XHTML 1.0:aa. header("Content-Type: text/html; charset=UTF-8");
Sama tieto on hyvä lisätä (X)HTML-koodin head-osioon:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
Lisäksi voit asettaa php.ini-tiedostoon merkistön:
default_charset = "UTF-8"
Minulla ei ole noista mitään käytöss tuolla. Mitä enemmän laitan noita, sitä enemmän sotkee.
Voisin alkaa tästä lähdin tallentamaan sivut joksikin muuksi, vaikka ISO-8859-1 koodatuiksi. Kai PHP tätä tukee paremmin?
Ärsyttää, kun aina kaikki jää jumiin tuohon ääkkös-juttuun. Toivottavasti PHP:n 6 versiossa olisi kunnon tuki ääkkösille.
~MIB
Älä viitsi poistella ja lähettää uudestaan viestejäsi, annat vain huonon kuvan itsestäsi. :(
Kyllä, PHP tukee yksitavuisia merkistöjä paremmin, eikö se jo käynyt keskustelusta ilmi? Se, että sait UTF-8-jutuilla koodisi entistä pahemmin rikki, tarkoittaa, ettet oikeastaan ymmärrä, mikä se UTF-8 on, miksi se vaatii erilaista käsittelyä ja miksi koodisi ei silloin toimi. Ei ole mikään ongelma saada kaikkea toimimaan UTF-8:n kanssa, mutta luultavasti säästät kaikkien hermoja, kun vaihdat ISO-8859-1:een. Tuskin kuitenkaan tarvitset vieraita merkistöjä (kuten kyrillisiä tai muita itämaisia), ja ainahan voit käyttää HTML-merkintöjä (€ jne.).
Kyllähän voin laittaa ääkköset näiksi ä, ö, jne merkeiksi, mutta sitten pitää taas säätää lisää: Koska koodini käsitelee merkin kerrallaan, niin sitä täytyy muokata.
No, laitampas vielä pari kysymystä:
1. Jos muuttaisin kaikki sivut tuoksi ISO-8859-1 merkistöön, niin missä muodossa editorini ne pitäisi tallentaa?
2. Tämä ISO-8859-1 siis osaa käsitellä ääkköset yhtenä merkkinä, ja PHP:n kanssa tälläinen ~keskitason koodaaja osaa sitä käyttää helpommin?
MIB kirjoitti:
1. Jos muuttaisin kaikki sivut tuoksi ISO-8859-1 merkistöön, niin missä muodossa editorini ne pitäisi tallentaa?
ISO-8859-1-muodossa. Windowsissa cp1252 (suomenkielisen Windowsin oletusmerkistö) on suunnilleen vastaava.
MIB kirjoitti:
2. Tämä ISO-8859-1 siis osaa käsitellä ääkköset yhtenä merkkinä, ja PHP:n kanssa tälläinen ~keskitason koodaaja osaa sitä käyttää helpommin?
Merkistö ei käsittele yhtään mitään, vaan merkistö on sopimus siitä, mitä asiat tarkoittavat. ISO-8859-1:ssä on sovittu, että tavu %E4 tarkoittaa ä-kirjainta, ja UTF-8:ssa on sovittu, että tavupari %C3%A4 tarkoittaa ä-kirjainta. PHP:n suunnittelijat ovat ajatelleet, että yksi tavu vastaa yhtä merkkiä, joten ISO-8859-1 toimii helposti oikein, koska siinä tosiaan yksi tavu on aina yksi merkki. Sen sijaan UTF-8:ssa merkki voi olla monen tavun mittainen, jolloin PHP käsittelee tekstiä väärin. Tällaisia merkistöjä varten on vasta jälkikäteen kehitelty PHP:hen paikkauksia ja purkkavirityksiä, ja siksi niiden käyttö vaatii jonkin verran tietämystä siitä, mistä kohti PHP:tä on paikattu ja mistä ei ja milloin asialla on merkitystä. (Sama tilanne on monessa muussakin vanhassa ohjelmointikielessä. Monia ei ole edes yritetty paikata, jolloin ongelmia ei ole, kun kaikki pitää tietää itse. ;] Jotkin taas on paikattu niin hyvin, että UTF-8 toimii jo hienosti.)
Mutta kyllä, sadannen kerran, ISO-8859-1:tä on helpompi käyttää.
Editorissani, Notepad++, ei ole tuollaista suoraan. Vaihtoehdot ovat: ANSI, UTF8 Without BOM, UTF8, UCS-2 Big Endian ja UCS-2 Little Endian.
Testaapa, toimisiko ANSI.
Kiitos! Nyt sain toimimaan :)
Edit. Katos, Grez otti vastauksen pois, kun oli samallainen kuin Metabolixella :D
Kysyisin vielä, että miksi tämä ei toimi?
<?php ... for($a = 0; $a < strlen($aakkoset); $a++) { $strpos2 = strpos($arvaukset, $aakkoset[$a]); if($strpos2 === false) { echo "<a href=\"$sivu?a=" . $_GET["a"] . $aakkoset[$a] . "\">" . $aakkoset[$a] . "</a> "; } else { echo "<u><strike>" . $aakkoset[$a] . "</strike></u> "; } } ... ?>
Se ei ikinä anna tulosta, että olisi jo arvattu ko. kirjain. Eli, jos on jo arvattu kirjain, niin sen pitäisi olla listassa yliviivattuna. Muuten linkkinä.
Miksi käytät sekaisin $_GET["a"]:ta ja $arvaukset-muuttujaa? Onko $arvaukset-muuttujan sisältö oikea? Oletko muistanut strtoupper-kutsun?
Tuollaisissa tapauksissa tulosta $aakkoset- ja $arvaukset-muuttujien sisällöt, niin pystyt päättelemään vian.
Metabolix keksikin sen jo... En ollut muistanut tuota strtoupper funktiota laittaa oikeaan kohtaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.