scanf formátumú karakterlánc - scanf format string

A scanf formátumú karakterlánc ( scan f ormatted) egy vezérlő paraméter, amelyet különféle funkciókban használnak a bemeneti karakterlánc elrendezésének megadására . Ezután a függvények feloszthatják a karakterláncot, és lefordíthatják a megfelelő adattípusok értékeire . A karakterlánc-szkennelési funkciókat gyakran a standard könyvtárak biztosítják .

A "scanf" kifejezés a C könyvtárból származik , amely népszerűsítette az ilyen típusú funkciókat, de az ilyen funkciók megelőzik a C-t, és más neveket is használnak, például readf az ALGOL 68-ban . A formázott bemenetet ( elemzést ) biztosító scanf formátumú karakterláncok kiegészítik a formázott kimenetet ( sablonokat ) biztosító printf formátumú karakterláncokat . Ezek egyszerűbb funkcionalitást és rögzített formátumot kínálnak a kifinomultabb és rugalmasabb elemzőkhez vagy sablonmotorokhoz képest, de sok célra elegendőek.

Történelem

Mike Lesk „s hordozható input / output könyvtár , köztük scanf hivatalosan része lett Unix 7-es verzió .

Használat

A C- ben scanf található függvény beolvassa a számok és más adattípusok bevitelét a szokásos bemenetből (gyakran parancssori felület vagy hasonló szöveges felhasználói felület ).

A következő C kód változó számú formázatlan tizedes egész számot olvas le a standard bemeneti adatfolyamból, és mindegyiket külön sorokra nyomtatja ki:

#include <stdio.h>

int main(void)
{
    int n;

    while (scanf("%d", &n) == 1)
        printf("%d\n", n);
    return 0;
}

A fenti program feldolgozása után egy szabálytalanul elosztott egész számok listája, például

456 123 789 456 12
456 1
      2378

a következőképpen jelenik meg:

456
123
789
456
12
456
1
2378

Szó kinyomtatása:

#include <stdio.h>

int main(void)
{
    char word[20];

    if (scanf("%19s", word) == 1)
        puts(word);
    return 0;
}

Nem számít, milyen adattípust akar a programozó elolvasni, az argumentumoknak (például a &n fentieknek) memóriára mutató mutatóknak kell lenniük . Ellenkező esetben a funkció nem fog megfelelően működni, mert a rossz memóriaszakaszokat írja felül, ahelyett, hogy a változó memóriahelyére mutatna, amelyhez bemenetet szeretne kapni.

Az utóbbi például egy cím-az üzemeltető ( & ) van nem használt érv: mint word a neve egy tömb az char , mint ilyen, (minden kontextusban, amelyben értékeli, hogy egy címet) egyenértékű egy mutatót az első a tömb eleme. Míg a kifejezés &word számszerűen értékelne ugyanarra az értékre, szemantikailag teljesen más jelentése van, mivel a teljes tömb címét jelenti, nem pedig annak egy elemét. Ezt a tényt szem előtt kell tartani, amikor a scanf kimenetet sztringekhez rendeljük .

Mivel scanf a jelöltek, hogy csak olvasható a szabványos bemenetről, sok programozási nyelvek felületek , mint például a PHP , van-származékok, például sscanf , és fscanf nem scanf maga.

Formátum karakterlánc specifikációk

A formázási helyőrzők a scanf többé-kevésbé ugyanaz, mint a printf , a fordított funkciója. A printf-hez hasonlóan a POSIX kiterjesztés n$ is meg van határozva.

Ritkán vannak konstansok (azaz olyan karakterek, amelyek nem formázzák a helyőrzőket ) egy formátum-karakterláncban, főleg azért, mert a programot általában nem arra tervezték, hogy ismert adatokat olvasson, bár scanf ezeket kifejezetten megadva elfogadja. A kivétel egy vagy több szóköz karakter, amely elveti az összes szóköz karaktert a bemenetben.

A leggyakrabban használt helyőrzők közül néhány következik:

  • %a  : Egy lebegőpontos szám beolvasása hexadecimális jelölésében.
  • %d  : Egész szám beolvasása aláírt tizedes számként.
  • %i  : Egész szám beolvasása aláírt számként. Hasonló %d , de a számot hexadecimálisként értelmezi, amikor előtte van, 0x és oktálisként, amikor előtte áll 0 . Például a karaktersorozat 031 31-nek %d és 25-nek olvasható %i . A bejelölt jelző h az a-ra %hi való átalakítást short és a-ba való hh konverziót jelzi char .
  • %u  : Tizedesjegy keresése unsigned int (Ne feledje, hogy a C99 szabványban a bemeneti érték mínuszjel opcionális, tehát ha mínuszjelet olvasunk, akkor nem keletkezik hiba, és az eredmény a kettő negatív számának kiegészítője lesz , valószínűleg nagyon nagy érték. Lásd strtoul() .) Ennek megfelelően %hu keres egy unsigned short és %hhu egy unsigned char .
  • %f  : Egy lebegőpontos szám beolvasása normál ( fixpontos ) jelöléssel.
  • %g , %G  : Lebegőpontos szám beolvasása normál vagy exponenciális jelöléssel. %g kisbetűket és nagybetűket %G használ.
  • %x , %X  : Egész szám beolvasása előjel nélküli hexadecimális számként.
  • %o  : Egész szám beolvasása oktális számként.
  • %s  : Karakterlánc beolvasása . A beolvasás a szóköznél véget ér . A karakterlánc végén egy null karakter tárolódik, ami azt jelenti, hogy a megadott puffernek legalább egy karakterrel hosszabbnak kell lennie, mint a megadott bemeneti hossz.
  • %c  : Karakter beolvasása (karakter). Nincs null karakter hozzáadva.
  • fehér szóköz : Bármely szóköz karakter beindítja a nulla vagy annál több szóköz karakter beolvasását . A szóköz karakterek számának és típusának nem kell egyeznie mindkét irányban.
  • %lf  : Szkennelés kettős lebegőpontos számként. "Float" formátum a "long" specifikátorral.
  • %Lf  : Beolvasás hosszú kettős lebegőpontos számként. A "Float" formátum a "long long" specifikációt.
  • %n  : Semmi nem várható. A beviteltől eddig elfogyasztott karakterek száma a következő mutatón keresztül tárolódik, amelynek int-nek kell lennie. Ez nem konverzió, és nem növeli a függvény által visszaadott számot.


A fenti lehet használni vegyület numerikus-módosítók és az l , L módosítók amely állni „hosszú” és „hosszú hosszú” között a százalékos szimbólum és a levél. A százalékjel és a betűk között számszerű értékek is lehetnek, amelyek megelőzik a long módosítókat, ha vannak ilyenek, amelyek meghatározzák a beolvasandó karakterek számát. Egy opcionális csillag ( * ) közvetlenül a százalék szimbólum után azt jelzi, hogy az e formátum-specifikátor által leolvasott nullapontot nem szabad egy változóban tárolni. Ehhez az elejtett változóhoz nem kell hozzáadni a argumentumot a formátumlánc mögött.

A ff printf-ben található módosító nincs jelen a scanf-ben, ami különbségeket okoz a bemeneti és kimeneti módok között. A ll és a hh módosítók nincsenek jelen a C90 szabványban, de a C99 szabványban.

Példa egy formátum karakterláncra

"%7d%s %c%lf"

A fenti formátum-karakterlánc az első hét karaktert tizedes egész számként beolvassa, majd a fennmaradó részt karakterláncként olvassa fel, amíg szóköz, újsor vagy tabulátor megtalálható, majd a szóköz elfogyasztását addig használja, amíg az első nem fehér szóköz karakter megtalálható, majd ezt a karaktert elfogyasztja, és végül megvizsgálja a többi karakter, mint egy dupla . Ezért egy megbízható programnak ellenőriznie kell, hogy a scanf hívás sikeres-e, és meg kell tennie a megfelelő intézkedéseket. Ha a bemenet nem a megfelelő formátumban volt, akkor a hibás adatok továbbra is a bemeneti adatfolyamban maradnak, és az új bemenet beolvasása előtt el kell dobni őket. Alternatív módszer, amely ezt elkerüli, fgets a beolvasott karakterlánc használata , majd vizsgálata. Az utolsó lépést sscanf például megteheti .

A sok lebegő típusú a, e, f, g esetében sok megvalósítás választja a legtöbbet ugyanabba az elemzőbe. A Microsoft MSVCRT e, f, g , míg a glibc mind a néggyel.

Sebezhetőségek

scanf sebezhető a formátum karakterlánc-támadásokkal szemben . Nagy gondot kell fordítani arra, hogy a formázó karakterlánc tartalmazzon korlátozásokat a karakterlánc és a tömb méretére vonatkozóan. A legtöbb esetben a felhasználó által beírt karakterlánc mérete tetszőleges, és a scanf függvény végrehajtása előtt nem határozható meg . Ez azt jelenti, hogy a %s hosszmeghatározó nélküli helyőrzők használata önmagában nem biztonságos és kihasználható a puffertúlcsordulásokhoz . Egy másik lehetséges probléma a dinamikus formázási karakterláncok engedélyezése, például a konfigurációs fájlokban vagy más, felhasználó által vezérelt fájlokban tárolt karakterláncok formázása. Ebben az esetben a karakterláncméretek megengedett bemeneti hossza nem adható meg, hacsak a formázási karakterláncot előzetesen nem ellenőrzik, és a korlátozásokat nem érvényesítik. Ehhez kapcsolódnak további vagy nem megfelelő formázási helyőrzők, amelyek nem egyeznek a tényleges vararg listával. Ezek a helyőrzők részben kivonhatók a veremből, vagy tartalmazhatnak nemkívánatos vagy akár nem biztonságos mutatókat, a varargok konkrét megvalósításától függően .

Lásd még

Hivatkozások

Külső linkek