Morjens ohjelmoinnin suurpäälliköt!
minulla on ongelma c koodin kanssa.
tämä on siis ihan noob tason kamaa mutta olen ilmeisesti ko. kurssin tunnilta ollut pois tai vastaavaa ja nyt en löydä mistään apua millä näkisin vastauksen suoraan.
alut ja loput poistettu koodista.
int a; printf("Anna kokonaisluku:"); scanf("%d", &a); if(a%2){ printf("Luku on pariton"); }
Nyt ongelma on se että kun käyttäjä täräyttää jonku luvun esim. 99 niin saan ainoastaan lisäämällä %d/n tulostuun "Luku 1 on pariton" vaikka haluaisin että luvun yksi tilalla on käyttäjän antama luku.
Eli itse ongelma on miten saan ulosprinttauksen väliin lisättyä ton käyttäjän asettaman lukuarvon ?
ei toiminut ("Luku" a "on pariton");
eikä ("Luku "/a"/ on pariton");
Olenko aivoton ?
Mod. korjasi kooditagit!
Ehkä olet tosiaan aivoton, kun et ole ollut tunnilla etkä löydä kurssin oppimateriaalia etkä edes käytä Googlea tai Putkan hakua. Suosittelen vastaisen varalta, että korjaat kaikki edellä mainitut. ^_^
Tässä on kuitenkin esimerkki printf-funktiosta:
int a = 1; float b = 2; char c = 'x'; char d[] = "hei"; printf("a = %d, b = %f, c = %c, d = %s\n", a, b, c, d);
Täng juu Metabolix...
Hain googlella sekä putkasta mutta kun en tiennyt oikein millä hakea muuta kuin printf:ssä scanf tallennettu tietue...
Jos et kerta hakua osaa käyttää, niin olisi kuitenkin suotavaa hakea ongelmaan ratkaisua Putkan oppaista.
Shooter99 kirjoitti:
Täng juu Metabolix...
Hain googlella sekä putkasta mutta kun en tiennyt oikein millä hakea muuta kuin printf:ssä scanf tallennettu tietue...
Yksinkertaisesti hakusanalla "printf" löytyy kaikki tarvittava tieto niin Putkasta kuin Googlellakin.
The Alchemist kirjoitti:
Yksinkertaisesti hakusanalla "printf" löytyy kaikki tarvittava tieto niin Putkasta kuin Googlellakin.
No jaa... ehkä siellä ei kuitenkaan kerrota esimerkiksi, että int-tyypin sijasta pitäisi käyttää long-tyyppiä, että scanf:n paluuarvo pitää aina testata ja että if(a%2) on turhan kryptinen varsinkin, jos on tarkoitus oppia alkeiden perusteita eikä osallistua Obfuscated C -kilpailuun.
Kannattaa lukea kurssimateriaali ihan alusta lähtien. Jos if(a%2) on opittu kurssilla, niin sitten kannattaa lukea jokin muu kurssimateriaali.
Yucca kirjoitti:
No jaa... ehkä siellä ei kuitenkaan kerrota esimerkiksi, että int-tyypin sijasta pitäisi käyttää long-tyyppiä
Miksi? Kyllähän tuolle voi suoraan syöttää: short, int ja long -tyyppejä, tällöin normaalit muunnos -ja korotussäännöt pätevät.
Yucca kirjoitti:
... ja että if(a%2) on turhan kryptinen varsinkin, jos on tarkoitus oppia alkeiden perusteita eikä osallistua Obfuscated C -kilpailuun.
Eikös jakojäännöksen ymmärtäminen kuulu ihan perusteisiin?
Eipä ainakaan minulle tule mitään lyhyempää tai selkeämpää tapaa parittomuuden testaamiseen. Bittitasolla vertailu (a & 1) ei sekään ole kumpaakaan noista. Myönnän, että tässä tapauksessa surkea whitespacen käyttö on omiaan kryptisyyttä lisäämään.
jalski kirjoitti:
Yucca kirjoitti:
No jaa... ehkä siellä ei kuitenkaan kerrota esimerkiksi, että int-tyypin sijasta pitäisi käyttää long-tyyppiä
Miksi? Kyllähän tuolle voi suoraan syöttää: short, int ja long -tyyppejä, tällöin normaalit muunnos -ja korotussäännöt pätevät.
Ei datassa syötetä tyyppejä. Mietipä, mitä tapahtuu koneissa, joissa int-tyypin lukualue on 16-bittinen.
jalski kirjoitti:
Yucca kirjoitti:
... ja että if(a%2) on turhan kryptinen varsinkin, jos on tarkoitus oppia alkeiden perusteita eikä osallistua Obfuscated C -kilpailuun.
Eikös jakojäännöksen ymmärtäminen kuulu ihan perusteisiin?
Obfuskointia on se, että if-lauseen ehtona on aritmeettinen lauseke. Toki sellainen kuuluu coolin ohjelmoinnin perinteisiin ja saattoi säästää tärkeitä mikrosekunteja 1950-luvun tietokoneissa, mutta ehkä nyt kuitenkin olisi järkevämpää kirjoittaa esimerkiksi if(a%2 != 0).
Yucca kirjoitti:
No jaa... ehkä siellä ei kuitenkaan kerrota esimerkiksi, että int-tyypin sijasta pitäisi käyttää long-tyyppiä. – – Mietipä, mitä tapahtuu koneissa, joissa int-tyypin lukualue on 16-bittinen.
Etkö tosiaan tiedä, että %d on int-tyyppiä varten, %ld on long-tyyppiä varten ja %hd on short-tyyppiä varten? Tämä ei millään tavalla riipu siitä, montako bittiä missäkin tyypissä on. Väärän tyypin käyttäminen on virhe, josta seuraa, että ohjelman toiminta on määrittelemätön. Normaalien muunnossääntöjen takia kokonaisluvut välitetään vähintään int-tyyppisinä, jolloin int ja sitä pienemmät muuttujatyypit sattumalta toimivat myös ristiin, suuremmat tyypit eivät.
Mietipä itse, mitä tapahtuu koneissa, joissa int-tyypin lukualue on 16-bittinen: 32-bittinen long-muuttuja voi täyttää kaksi %d:tä ja pilata koko tulosteen. Sama tapahtuu myös 32-bittisellä int-tyypillä ja 64-bittisellä long long -tyypillä. (Sen sijaan 64-bittisessä Linuxissa nähtävästi luvut siirretään aina 64-bittisinä, jolloin myös 32-bittinen int ja 64-bittinen long toimivat ristiin.)
Jos mielessäsi oli jokin muu syy sille, miksi "pitäisi käyttää long-tyyppiä", ole hyvä ja kerro se suoraan äläkä heittele epämääräisiä kommentteja, joista saa vain sen käsityksen, että luulet tietäväsi C:stä jotain ihmeellistä mutta oikeasti olet vain väärässä.
Metabolix kirjoitti:
Jos mielessäsi oli jokin muu syy sille, miksi "pitäisi käyttää long-tyyppiä", ole hyvä ja kerro se suoraan äläkä heittele epämääräisiä kommentteja
Tarkoitukseni ei ollut kirjoittaa tänne C-kielen oppikirjaa, vaan viitata siihen, että numeeristen tyyppien käytön periaatteita ei todellakaan kerrota printf-funktion dokumentaatiossa.
Jos et ole C-kielen alkeita opetellessasi ymmärtänyt sitä, että käyttäjältä luettavan kokonaislukudatan tyyppinä on syytä käyttää long-tyyppiä, on aika kerrata ne alkeet.
Sitten kun ymmärretään, mitä tyyppiä pitää käyttää, on aika katsoa, mitä formaattia sille käytetään. Se muuten sitten löytyy scanf-funktion osalta scanf-funktion dokumentaatiosta, ei printf-funktion.
Yucca kirjoitti:
Numeeristen tyyppien käytön periaatteita ei todellakaan kerrota printf-funktion dokumentaatiossa.
Kukaan ei ole väittänytkään niin, ja kun kerran puhe oli printf-funktiosta eikä numeeristen tyyppien käytön periaatteista, olisi ollut viisasta kertoa jo aiemmin, että aiot vaihtaa aihetta.
Yucca kirjoitti:
Käyttäjältä luettavan kokonaislukudatan tyyppinä on syytä käyttää long-tyyppiä.
Voisit edes yrittää perustella tuollaisia mielivaltaisia väitteitäsi. Ei ole syytä käyttää ehdottomasti mitään tiettyä tyyppiä eikä varsinkaan ehdottomasti juuri long-tyyppiä. Yhtä järkevää olisi väittää, että ihmiselle sitomispuuhissa ei riitä metrin naru mitenkään vaan narua on syytä olla tasan kaksi metriä joka tilanteessa.
Tyypin vaihtaminen ei ratkaise ongelmia täydellisesti vaan siirtää ne myöhemmäksi. Jos int-tyyppi on 16-bittinen, long-tyyppi on luultavasti vain 32-bittinen eikä riitä edes maailman väkiluvun tai Blu-ray-levyn tavumäärän ilmaisemiseen. Toisaalta jo 16-bittinen short-tyyppi riittää erinomaisesti vaikka varpaiden tai väitöskirjan sivujen laskemiseen, joten monissa tapauksissa long-tyypin käyttö on aivan turhaa.
Suurten lukujen käsittelyyn loogisia valintoja ovat maxint_t ja liukuluvut. Jos nämä eivät riitä, ainoa varma ratkaisu on kirjoittaa pidempi koodi, joka käsittelee liian suuret luvut järkevästi silloinkin, kun ne eivät mahdu mihinkään sopivaan lukumuuttujaan.
En kiellä, etteikö long-tyyppi olisi useimmissa tapauksissa riittävä ja joissain käyttötarkoituksissa int-tyyppiä parempi siinä harvinaisessa mutta onnekkaassa tilanteessa, että on ylipäänsä tarkoitus tukea useampaa ympäristöä. Kuitenkin monet tekevät joka tapauksessa koodinsa niin, että se toimii vain tietyillä alustoilla (ja 32-bittisellä int-tyypillä), eikä int-tyypin käyttö suinkaan ole silloin suurin este alustan vaihdolle.
Metabolix kirjoitti:
Yucca kirjoitti:
Numeeristen tyyppien käytön periaatteita ei todellakaan kerrota printf-funktion dokumentaatiossa.
Kukaan ei ole väittänytkään niin
On: ”Yksinkertaisesti hakusanalla "printf" löytyy kaikki tarvittava tieto”.
Kysyjä *todellakin* tarvitsee muutakin perustietoa kuin printf-funktion dokumentaation.
Yucca kirjoitti:
On: ”Yksinkertaisesti hakusanalla "printf" löytyy kaikki tarvittava tieto”.
Kysyjä *todellakin* tarvitsee muutakin perustietoa kuin printf-funktion dokumentaation.
Vänkääminen on tietysti aina hauskaa, mutta aloituspostissa ilmoitetun ongelman ratkaisemiseen kysyjä ei juuri muuta tarvitse, kun dokumentaatioissa on yleensä ihan kattavat esimerkit, joista soveltaa kehnompikin koodari.
Olennaisempi kysymys kuin kokonaislukutyypin bittimäärä (tai lukualue) tuntuisi olevan kunnollinen virheenkäsittely, ja sen toteuttamisessa scanf on onneton: se ei pysty mitenkään ilmaisemaan, että käyttäjä on syöttänyt liian ison luvun. Itse asiassa, scanfia ei (tutustuttamiskurssin ulkopuolella) pitäisikään käyttää interaktiivisen syötteen parsimiseen; se kun ei toisinaan ole kovinkaan tarkasti muotoiltua ("formatted"). scanfilla voi toki lukea sellaista, mitä on printf:llä aiemmin kirjoittanut (varauksin).
strtol sen sijaan osaa kertoa jos merkkijonon sisältämä luku ei mahdu long-tyyppiseen muuttujaan, jonka jälkeen voi itse tarkistaa mahtuuko luku mahdollisesti pienempään käytössä olevaan muuttujaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.