Itse en ole onnistunut tässä: Miten voi esim. scanf()- tai gets()-funktiolla ottaa vastaan merkkijonon, jossa on välilyöntejä ilman, että se katkeaa ensimmäisen välilyönnin kohdalla?
Jos edellämainituilla funktioilla ei voi, niin millä voisi (ja miten).
iostreamia en mielellään käyttäisi, se kun on hieman isohko (~460 kt / .exe, kun taas esim stdio + stdlib ~20 - 25 kt /.exe ja tilasta muutenkin koneella pulaa :) )
Jos scanf-kutsu on seuraavaa muotoa:
scanf ("%100[abc]", merkkijono);
niin se tarkoittaa, että luetaan enintään 100 merkkiä merkkijonomuuttujaan, ja merkit ovat joukosta 'a', 'b' ja 'c'. Merkkijonon pituus tulisi olla 101, mikäli oikein muistan, koska C-kielessä on merkkijonon loppumerkkinä \0, ja scanf-lisää sen lukemiensa merkkien loppuun.
Tämä ei ole kovin hyödyllistä kuitenkaan. Haluat muitakin merkkejä. Siispä voit käyttää []-merkinnän lisäominaisuutta, jossa annetaankin merkit, joita ei lueta. Nyt merkintä [^\n] tarkoittaa, että luetaan kaikkia merkkejä paitsi rivinvaihtoa. Heti kun tulee rivinvaihto vastaan, luku loppuu ja rivinvaihto jää luettavien merkkien puskuriin. Kaiken muun saat merkkijonoosi.
Jos puolestaan haluat siivota syötteen rivinvaihtoon asti, voit tehdä näin scanf-kutsun jälkeen:
while (getchar() != '\n') /* ei mitään */ ;
Tämä lukee syötettä kunnes tulee rivinvaihto ja poistaa kaiken lukemansa mukaan lukien rivinvaihto. Sen jälkeen seuraavan rivin lukeminen onnistuu taas samanlaisella scanf-kutsulla.
Puutteena on se, että jos käyttäjä antaa yli 100 merkkiä pitkän rivin, osa siitä menee hukkaan. Lukua 100 ja vastaavaa merkkijonoa isontamalla tämä ongelma tietenkin voidaan yleensä varoa.
Siis (varo, tarkasti testaamatonta koodia!):
char mjono [101]; printf ("Odotan merkkijonoa syötteeksi:\n"); scanf ("%100[^\n]", mjono); while (getchar() != '\n') /* siivous */ ; printf ("Sanoit:\n%s\n", mjono);
Nyt kun olen näyttänyt, miten se (toivon mukaan) onnistuu scanf-funktiolla, tulisi mieleen lisätä, että näin ei kannata tehdä. Mielestäni scanf:n ymmärtämät merkkijono-ohjeet ovat sekavia ja alttiita virheille. Vain yksinkertaisissa tapauksissa sen käyttö on hyvä idea.
Scanf-funktion dokumentaatiossa kerrotaan kaikki ohjeet, mitä sille voi antaa merkkien ja muun tiedon lukemisesta, jos kuitenkin haluat käyttää sitä. Sen sijaan voisin suositella toista ratkaisua.
Olisiko seuraava kirjasto sopiva sinulle?
http://bstring.sourceforge.net/
http://bstring.sourceforge.net/bstrFAQ.shtml
"A minimum useage of Bstrlib measured on a variety of compilers shows an additional object code size of between 18k and 28K."
BSD-lisenssi ei vaadi kohtuuttomia. Sinun ei tarvitse jaella sorsiasi, jos et halua.
Kummallista, jos iostream aiheuttaa tuollaisen koon ohjelmalle. Kokeilepa säätää asetuksista päälle valinta "strip executable" sekä mahdollisesti jokin optimointi (miksei sitten vaikka koko-optimointi).
Aika outo juttu, kun kyllä se minulla ainakin gets():llä ottaa välilyönnitkin mukaan.
Kyllä iostream voi olla melkoisesti stdiota suurempi, koska iostreamissa asiat tehdään paljolti templaateilla, kun taas stdio on perinteistä kirjastofunktiokamaa.
Tuo kokoero riippuu myös kääntäjästä, ympäristöstä ja jaettujen kirjastojen käytöstä. Microsoftin C++:lla käännetty simppeli cout << "Hello world!\n";
näyttäisi olevan 7680 tavua ja C:llä printf("Hello world!\n");
on 5632 tavua.
EDIT: Niin ja jos asia ei nyt vieläkään ole kaikille selvä, niin gets-funktiota EI saa ikinä koskaan käyttää. Jos tuolle tielle on joutunut, niin sitten edes fgets.
Aihe on jo aika vanha, joten et voi enää vastata siihen.