C/Standardikirjastot/stdio.h/printf-kaavat

#include <stdio.h>

*printf ja *scanf-funktioiden kaavat ovat merkkijonoja, joissa muuttujat ilmaistaan ns. muotoilumääritteillä prosenttimerkillä alkavilla sarjoilla.

Muiden merkkien tapauksessa:

  • printf: merkki tulostetaan sellaisenaan
  • scanf:
    • jos merkki on välilyönti, virrasta luetaan tyhjät merkit (välilyönnit, rivinvaihdot, sarkaimet, ym.) pois alta
    • muussa tapauksessa virrasta luetaan merkki, ja jos se ei täsmää kaavan merkkiin, scanf keskeyttää lukemisen ja palaa sitä kutsuneeseen koodiin; seuraavia kenttiä ei lueta.

Muotoilumäärite koostuu useasta osasta: prosenttimerkistä, valinnaisista lisämääreistä, valinnaisesta leveydestä, valinnaisesta tarkkuudesta, ja tietotyypistä. Ainoa poikkeus on määrite %%, joka vastaa prosenttimerkkiä sellaisenaan.

  • printf: %[MUOTOILUMÄÄREET][LEVEYS][.TARKKUUS][KOKOMÄÄRE]TYYPPI
  • scanf: %[MUOTOILUMÄÄREET][LEVEYS][KOKOMÄÄRE]TYYPPI

Tyyppi voi olla mikä tahansa seuraavista:

printf/scanf-tietotyypit ja niiden tunnukset
Tyypin
tunnus
printf scanf
Tietotyyppi Selite Tietotyyppi Selite
i int Etumerkillinen kokonaisluku desimaalimuodossa. int * Etumerkillinen kokonaisluku.
Jos merkit alkavat nollalla, luvun oletetaan olevan oktaalimuodossa;
jos 0x tai 0X, luvun oletetaan olevan heksadesimaalimuodossa;
muuten se luetaan desimaalimuodossa.
d Etumerkillinen kokonaisluku desimaalimuodossa.
u unsigned int Etumerkitön kokonaisluku desimaalimuodossa. unsigned int * Etumerkitön kokonaisluku desimaalimuodossa.
Jos luvussa on etumerkki, etumerkillinen luku muunnetaan etumerkittömäksi.
o Etumerkitön kokonaisluku oktaalimuodossa. Etumerkitön kokonaisluku oktaalimuodossa.
x
X (printf)
Etumerkitön kokonaisluku heksadesimaalimuodossa.
Kirjainten A-F kirjainkoko vastaa tunnuksen kirjainkokoa.
Etumerkitön kokonaisluku heksadesimaalimuodossa.
Kirjainkoolla ei merkitystä.
f
F (printf)
(float) → double Liukuluku desimaalimuodossa. float * Liukuluku, jossa on mahdollisesti etumerkki, desimaalipiste/pilkku
ja/tai kymmenpotenssimuodon eksponenttiosa (e/E + (etumerkki) + luku).
[C99] Heksadesimaaliliukulukumuotoa tuetaan myös, jos merkit alkavat 0x/0X.
e
E (printf)
Liukuluku kymmenpotenssimuodossa. Kirjainkoot vastaavat tyyppitunnuksen kirjainkokoa.
g
G (printf)
Liukuluku desimaali- tai kymmenpotenssimuodossa, riippuen siitä, kumpi on lyhyempi. Kirjainkoot vastaavat tyyppitunnuksen kirjainkokoa.
[C99] a
[C99] A (printf)
Liukuluku heksadesimaalimuodossa. Kirjainkoot vastaavat tyyppitunnuksen kirjainkokoa.
c (char) → int Merkki. char * Yksi tai useampi merkki.
s const char * Merkkijono. Lukee merkkejä seuraavaan tyhjään merkkiin (esim. välilyönti) saakka.
p const void * Osoitin. Tarkka muoto riippuu toteutuksesta. void ** Osoitin. Tarkka muoto riippuu toteutuksesta.
[...] (ei sallittu) char * Lukee puskuriin hakasulkeiden välissä olevia merkkejä
niin pitkään kun niitä riittää.
[^...] Lukee puskuriin merkkejä, jotka eivät ole hakasulkeiden välissä,
niin pitkään kun niitä riittää.
n int * Mitään ei kirjoiteta, vaan yhteensä tähän asti kirjoitettujen merkkien määrä sijoitetaan osoittimen osoittamaan muistipaikkaan. int * Mitään ei lueta, vaan yhteensä tähän asti luettujen merkkien määrä sijoitetaan osoittimen osoittamaan muistipaikkaan.

Kokomääreet muuttavat tietotyyppejä seuraavasti (printf:lle, scanf:lle vastaavasti osoittimen tietotyyppejä, paitsi n). Huomaa, että tyyppikorotukset pätevät, joten printf:n (muttei scanf:n) kohdalla automaattisesti floatdouble, signed charint, unsigned charunsigned int, shortint, unsigned shortunsigned int:

Kokomääreiden vaikutus tietotyyppeihin
Tyyppitunnus
Kokomääre d, i u, o, x f, e, g, [C99] a c s [(^)...] n
int unsigned int float char (*) int *
[C99] hh char unsigned char × × char *
h short unsigned short × × short *
l long unsigned long double wchar_t (*) long *
[C99] ll long long unsigned long long × × long long *
[C99] j intmax_t uintmax_t × × intmax_t *
[C99] z size_t size_t × × size_t *
[C99] t ptrdiff_t ptrdiff_t × × ptrdiff_t *
L × × long double × ×

Jos kokomääreen ja tyyppitunnuksen yhdistelmää ei näytetä taulukossa tai sen kohdalla on ×, se ei ole sallittu.

Jos leveitä merkkejä käytetään sellaisen printf:n ja scanf:n kanssa, joka ei natiivisti käytä niitä, tai päinvastoin, merkkimuunnokset suoritetaan automaattisesti; jos tapahtuu virhe, printf/scanf keskeyttää suorituksensa.

Leveys
  • printf: Ei-negatiivinen kokonaisluku tai *. Ilmoittaa toivotun kentän leveyden. Jos kenttä ei ole tarpeeksi leveä, sitä täydennetään välilyönneillä niin, että teksti tasataan oikeaan reunaan. Jos leveys on *, leveys luetaan int-tyyppisestä argumentista ennen varsinaista arvoa.
  • scanf: Ei-negatiivinen kokonaisluku. Ilmoittaa, montako merkkiä saa enintään lukea tämän kentän kohdalla.
Tarkkuus
  • printf: Ei-negatiivinen kokonaisluku tai *. Tarkkuuden eteen kirjoitetaan aina piste, jotta sen voi erottaa leveydestä. Jos kirjoitetaan pelkkä piste, tarkkuudeksi luetaan 0. Jos tarkkuus on *, tarkkuus luetaan int-tyyppisestä argumentista ennen varsinaista arvoa (mutta leveyden jälkeen, jos sekin on *).
    • Kokonaisluvuilla tarkkuus määrää, miten monta numeroa luvusta vähintään kirjoitetaan. Jos numeroita ei ole riittävästi, alkuun kirjoitetaan tarpeellinen määrä nollia. Oletustarkkuus on 1; jos tarkkuudeksi asettaa nollan, lukua 0 ei kirjoiteta lainkaan.
    • Liukuluvuilla tarkkuus määrää, miten monta numeroa kirjoitetaan pisteen jälkeen (oletus: 6), tai g/G:llä merkitsevien numeroiden lukumäärän.
    • Merkkijonoilla tarkkuus määrää, miten monta merkkiä jonosta enintään kirjoitetaan.
Muotoilumääreet
printf:n muotoilumääreet
Määre Selite
- Jos kenttä ei ole tarpeeksi leveä, se tasataan vasemmalle, eikä oikealle.
+ Kirjoittaa plus-merkin positiivisten lukujen eteen.
 (väli) Kirjoittaa välilyönnin positiivisten lukujen eteen niin, ettei miinusmerkin takia luvut ole yhden numeron verran sivussa.
0 Tasaa kenttää välilyöntien sijasta nollilla.
# Vaihtaa eri kenttien esitysmuotoa:
  • Oktaaliluvut (o): kirjoittaa nollan luvun eteen.
  • Heksadesimaaliluvut (x): kirjoittaa 0x/0X luvun eteen.
  • Liukuluvut: kirjoittaa desimaalipisteen/pilkun aina, vaikka sen perässä ei olisikaan mitään.
scanf:n muotoilumääreet
Määre Selite
* Kenttä luetaan, mutta tulosta ei tallenneta mihinkään, eikä kenttää lasketa lopulliseen scanf:n palauttamaan lukumäärään.

Huomioita

muokkaa
  • scanf: jos yksikään merkki kentän alussa ei vastaa tyyppiä, scanf keskeyttää suorittamisensa, eikä lue sitä tai myöhempiä kenttiä.

printf-esimerkkejä

muokkaa
 printf("Nimesi on %s, ja olet %d-vuotias.\n", "Matti", 42);
 /* Nimesi on Matti, ja olet 42-vuotias. */
 printf("[ %+10.3f %+10.3f %+10.3f %+10.3f %+10.3f ]\n", -0.8, -0.4, 0.0, 0.4, 0.8);
 /* [     -0.800     -0.400     +0.000     +0.400     +0.800 ] */
 printf("Kirjoitettiin %#lx tavua.\n", 1600);
 /* Kirjoitettiin 0x640 tavua. */
 printf("Lataus %1.2f %%\n", 100.0 * 4096 / 9327);
 /* Lataus 43.92 % */

scanf-esimerkkejä

muokkaa
 float paino_kg;
 sscanf("5.0 kg", "%f kg\n", &paino_kg);
 /* paino_kg = 5.0f */