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 áll0. Például a karaktersorozat03131-nek%dés 25-nek olvasható%i. A bejelölt jelzőhaz a-ra%hivaló átalakítástshortés a-ba valóhhkonverziót jelzichar. -
%u: Tizedesjegy kereséseunsigned 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ásdstrtoul().) Ennek megfelelően%hukeres egyunsigned shortés%hhuegyunsigned 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.%gkisbetűket és nagybetűket%Ghaszná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
- - A rendszerinterfészek referenciája, az egységes UNIX specifikáció , 7. szám a nyílt csoporttól
- C ++ referencia
std::scanf