Onnistuuko kaksiulotteiseen char taulukkoon t[x][y] (taulukko olisi kokoa t[3][3] ) tekemään niin, että ensin kysyy vaikka pituuden ja sijoittee ne alkoihin t[x] ja sitten kysyy nimiä ja sijoittaa ne alkioihin t[y]. Eniten minua tässä mietityttää se, että miten saan laitettua nimiä alkioihin t[y]? eikös ne nyt ottaisi vain yhden kirjaimen ?
Mitähän oikein tarkoitat? 2-ulotteinen char-taulukko t[3][3] sisältää siis 3*3 merkkiä (tai 8-bittistä kokonaislukua):
... ... ...
Jos nyt ymmärsin oikein, kaipasit jotakin tällaista: (linkit vanhentuneet). (Näyttää muuten aika veikeältä tuo lähdekoodi selaimella katseltuna, kannattaa mieluummin tallentaa ensin :)
Tekstille siis varataan tilaa, kun sen pituus tiedetään. Teksti tallennetaan char-taulukkoon eli char-osoittimen päähän. Lopuksi pitää muistaa vapauttaa tila.
Ei hyvää päivää.
Onko kyseessä C vai C++? Jos C++, niin eiköhän kannattaisi tutustua standardikirjastoon ja esimerkiksi vector- ja string-luokkiin. Säästyt monelta ongelmalta niiden avulla.
Jos taas kyse on C:stä, voi siinäkin homman tehdä paljon siistimmin ja paremmin kuin miten se on tuossa Metabolixin esimerkissä esitetty. Ainakin seuraaviin kiinnittäisin huomiota: goto-lauseet pois, pari funktiota kehiin, pari silmukkaa käyttöön, pituuden tarkistukseen nolla ja negatiiviset, fgets-funktio käyttöön.
En myöskään selkeyden vuoksi nimeäisi mainin parametreja uudelleen.
No selkeys ja selkeys. Minä olen tottunut Pascalin nimityksiin, ja kyllä ParamCount kertoo selvästi enemmän kuin argc, saatikka sitten argv (mistä ihmeestä se v edes tulee? value?)
Gotossa ei ole yhtään mitään vikaa, kun tietää, mitä tekee eikä käytä sitä turhaan ja/tai varomattomasti.
Koska tein esimerkin, jonka on tarkoitus vain havainnollistaa toimintaa, en kiinnittänyt huomiota siihen, että joku syöttäisi nollan tai negatiivisen luvun. Eiköhän sitä jokainen osaa itse lisätä sen samaan if-lauseeseen kuin muutkin tarkistukset.
Mihin sitä fgets-funktiota sitten vielä tarvittaisiin? Ja minä en ainakaan näe syytä laittaa noin lyhyitä juttuja funktioihin, jos ne eivät tuon useammin toistu, ja koska tämä edelleenkin oli vain esimerkki, jossa haetaan nimenomaan kolme nimeä, kirjoitin nuo kolme auki, ettei tarvitsisi ylimääräistä silmukkaa tehdä. Ja koska se on esimerkki, en tehnyt sitä muutenkaan huolella, sillä se on tarkoitettu luettavaksi pyytäjälle, jotta hän voisi oppia siitä uutta, ei suoraan kopioitavaksi, jolloin oppimista ei tapahdu.
Aina, kun käsket muuttaa koodia jotenkin (paitsi jos siellä on selkeä virhe), perustele! Hiukkasen nipon oloinen tuo asenteesi, ei millään pahalla. Tai sitten olen vain vainoharhainen.
Metabolix kirjoitti:
argv (mistä ihmeestä se v edes tulee? value?)
Vector.
Huonoista esimerkeistä lukija oppii vähemmän kuin hyvistä. Jos esimerkki on vain esimerkki, ei sitä yleensä voi edes sellaisenaan suoraan hyödyntää, jolloin lukijan täytyy ymmärtää saamansa esimerkkikoodi, jotta voi soveltaa sitä omaan ongelmaansa. Näin ollen esimerkit kannattaa laatia huolella.
Oletin, että jos luet fgets-funktion kuvauksen, et tarvitse perusteluita siihen, miksi sitä suosittelin. Nyt tyhjennät puskurin silmukassa, vaikka voisit lukea puskurin kerrallaan rivinvaihtoon saakka fgetsillä. Kannattaako keksiä pyörä uudelleen vai käyttää standardikirjaston funktiota hyväksi, varsinkin esimerkissä?
Samoin yleisessä tiedossa jo ainakin parikymmentä vuotta on ollut se, että goton sijaan kannattaa yleensä käyttää muunlaista rakennetta, jota lukijan on helpompi seurata ja koodia siten helpompi ymmärtää ja ylläpitää.
Jos jokin sama tai melkein sama asia tehdään koodissa useampaan otteeseen, olipa se kaksi tai kolme riviä tai sata riviä pitkä pätkä, on siitä syytä kirjoittaa silmukka ja eristää kyseinen pätkä funktioksi. Ilman eristämistä koodin ylläpito menee hankalaksi, koska pienikin muutos täytyy muistaa tehdä kaikkiin paikkoihin. Useimmiten käy unohdus niin kuin esimerkin kirjoittajalla, koska ensimmäisen nimen lukemisen yhteydessä testataan sen pituutta 63:a merkkiä vastaan ja muissa 64:ä merkkiä vastaan. Tai ehkä ymmärsin koodin tuolta osin väärin.
Jos kirjoittaa esimerkin, josta jättää jotakin pois, on syytä kommentoida se pois jätetty osa. Eli aivan hyvin olisit voinut lisätä kommentin, jossa olisi mainittu nollan ja negatiivisten tarkistuksen tarpeesta. Näin myöhemminkin esimerkkiä lukeva saa sen kuvan, että olit ajatellut asiaa, mutta jättänyt sen vain toteuttamatta.
Ja mitä tulee noiden nimeämiseen, olisiko parempi pitäytyä standardin mukaisessa tavassa vai keksiä oma? Väitän, että standardin mukainen tapa lisää koodin ymmärrystä ja nopeuttaa oppimista, kun ei tarvitse jokaisen ohjelmoijan koodista oppia niitä samoja asioita hieman eri nimillä kerta toisensa jälkeen.
C++:n osalta olisi niin paljon muutettavaa, etten jaksa tähän niitä kaikkia edes listata. Koko esimerkki olisi parempi kirjoittaa uusiksi.
Edellinen kommenttini oli tarkoituksella pistävä, koska niin moni asia tehdään liian usein väärin, vaikka helpompi ja parempi tapa olisi olemassa. Ohjelmoinnissa, varsinkin jos tehdään esimerkkejä muille, on otettava huomioon ne muut itsensä lisäksi. Samalla uskon, että sait itsekin hyödyllisiä tietoja, koska en muuten näe mitään syytä, miksi olet käyttänyt tapoja, jotka on tunnetusti huonoja tai joiden tekemiseksi on valmiita funktioita.
Aihe on jo aika vanha, joten et voi enää vastata siihen.