scanf format streng - scanf format string
En scanf formatstreng ( scanning f ormatted) er en kontrol parameter anvendes i forskellige funktioner til at angive layoutet af en input string . Funktionerne kan derefter dele strengen og oversætte til værdier af passende datatyper . String-scanning funktioner leveres ofte i standard biblioteker .
Udtrykket "scanf" kommer fra C-biblioteket , som populariserede denne type funktion, men sådanne funktioner går forud for C, og andre navne bruges, såsom readf i ALGOL 68 . scanf-formatstrenge, der giver formateret input ( parsing ), er komplementære til printf-formatstrenge , som giver formateret output ( skabelonindstilling ). Disse giver enkel funktionalitet og fast format sammenlignet med mere sofistikerede og fleksible parsere eller skabelonmotorer, men er tilstrækkelige til mange formål.
Historie
Mike Lesk 's bærbare input / output bibliotek , inklusive scanf , blev officielt en del af Unix i version 7 .
Anvendelse
Den scanf funktion, som findes i C , læser input for numre og andre datatyper fra standard input (ofte en command line interface eller lignende form for en tekst brugergrænseflade ).
Følgende C-kode læser et variabelt antal uformaterede decimale heltal fra standard input stream og udskriver hver af dem på separate linjer:
#include <stdio.h>
int main(void)
{
int n;
while (scanf("%d", &n) == 1)
printf("%d\n", n);
return 0;
}
Efter at være blevet behandlet af ovenstående program, vises en uregelmæssigt fordelt liste over heltal som f.eks
456 123 789 456 12
456 1
2378
vises konstant fordelt som:
456 123 789 456 12 456 1 2378
Sådan udskrives et ord:
#include <stdio.h>
int main(void)
{
char word[20];
if (scanf("%19s", word) == 1)
puts(word);
return 0;
}
Ligegyldigt hvad den datatype programmøren ønsker programmet til at læse, argumenterne (såsom &n ovennævnte) skal være pejlemærker peger på hukommelsen. Ellers fungerer funktionen ikke korrekt, fordi den forsøger at overskrive de forkerte dele af hukommelsen i stedet for at pege på hukommelsesplaceringen for den variabel, du forsøger at få input til.
I det sidste eksempel en adresse-operatør ( & ) er ikke anvendes til argumentet: som word er navnet på en opstilling af char , som sådan er (i alle sammenhænge, hvor det evalueres til en adresse) svarende til en pointer til den første element i arrayet. Mens udtrykket &word numerisk vurderes til den samme værdi, har det semantisk en helt anden betydning, idet det står for adressen på hele arrayet snarere end et element i det. Denne kendsgerning skal huskes, når man tildeler scanf output til strenge.
Som det scanf er udpeget til kun at læse fra standardinput, har mange programmeringssprog med grænseflader , såsom PHP , derivater som sscanf og fscanf men ikke scanf sig selv.
Formater strengspecifikationer
Formateringen pladsholdere i scanf er mere eller mindre den samme som i printf , dens omvendte funktion. Som i printf er POSIX-udvidelsen n$ defineret.
Der er sjældent konstanter (dvs. tegn, der ikke formaterer pladsholdere ) i en formatstreng, hovedsageligt fordi et program normalt ikke er designet til at læse kendte data, men scanf accepterer disse, hvis de udtrykkeligt er specificeret. Undtagelsen er et eller flere tegn i mellemrummet , som kasserer alle mellemrumstegn i input.
Nogle af de mest anvendte pladsholdere følger:
-
%a: Scan et flydende nummer i dets hexadecimale notation. -
%d: Scan et heltal som et underskrevet decimaltal . -
%i: Scan et heltal som et underskrevet nummer. Svarende til%d, men fortolker tallet som hexadecimal, når det indledes0xog oktalt, når det indledes0. For eksempel031læses strengen som 31 ved hjælp af%dog 25 ved hjælp af%i. Flaggethi%hiangiver konvertering til enshortoghhkonvertering til enchar. -
%u: Scan efter decimalunsigned int(Bemærk at i C99-standarden er inputværdien minustegn valgfri, så hvis et minustegn læses, opstår der ingen fejl, og resultatet bliver de to komplement af et negativt tal, sandsynligvis en meget stor værdi. Sestrtoul().) Tilsvarende%huscanner efter enunsigned shortog%hhuefter enunsigned char. -
%f: Scan et flydende nummer i normal notation ( fast punkt ). -
%g,%G: Scan et flydende nummer i normal eller eksponentiel notation.%gbruger små bogstaver og%Gbruger store bogstaver. -
%x,%X: Scan et heltal som et usigneret hexadecimalt tal. -
%o: Scan et heltal som et oktalt tal. -
%s: Scan en tegnstreng . Scanningen afsluttes i det hvide rum . Et nultegn er gemt i slutningen af strengen, hvilket betyder, at den leverede buffer skal være mindst et tegn længere end den angivne inputlængde. -
%c: Scan et tegn (tegn). Intet null-tegn er tilføjet. - hvidt mellemrum : Alle hvide mellemrumstegn udløser en scanning for nul eller flere mellemrumstegn . Antallet og typen af mellemrumstegn behøver ikke at matche i begge retninger.
-
%lf: Scan som et dobbelt flydende nummer. "Flyd" -format med "lang" -specifikatoren. -
%Lf: Scan som et langt dobbelt flydende nummer. "Float" formaterer "lang lang" -specifikatoren. -
%n: Intet forventes. Antallet af tegn, der er forbrugt hidtil fra input, gemmes gennem den næste markør, som skal være en markør til int. Dette er ikke en konvertering og øger ikke antallet, der returneres af funktionen.
Den ovenfor kan anvendes i forbindelse med numeriske modifikatorer og de l , L modifikatorer der står for "lange" og "lang lang" i mellem procent symbol og brevet. Der kan også være numeriske værdier mellem procentsymbolet og bogstaverne, forud for eventuelle long modifikatorer, der angiver antallet af tegn, der skal scannes. En valgfri stjerne ( * ) lige efter procentsymbolet angiver, at det nulpunkt, der læses af dette format, ikke skal lagres i en variabel. Intet argument bag formatstrengen skal medtages for denne droppede variabel.
Den ff i printf er ikke til stede i scanf, der forårsager forskellene mellem former for input og output. Den ll og hh modifikatorer er ikke til stede i C90 standarden, men er til stede i C99-standarden.
Et eksempel på en formatstreng er
"%7d%s %c%lf"
Ovenstående formatstreng scanner de første syv tegn som et decimaltal, læser derefter de resterende som en streng, indtil der findes et mellemrum, en ny linje eller en fane, derefter forbruges det hvide mellemrum, indtil det første ikke-hvide mellemrumstegn findes, og derefter forbruges det tegn og til sidst scanner de resterende tegn som en dobbelt . Derfor skal et robust program kontrollere, om scanf opkaldet lykkedes, og tage passende skridt. Hvis input ikke var i det korrekte format, vil de fejlagtige data stadig være på inputstrømmen og skal kasseres, før nyt input kan læses. En alternativ metode, der undgår dette, er at bruge fgets og derefter undersøge indlæst streng. Det sidste trin kan f.eks. Udføres ved sscanf .
I tilfældet med de mange flydetypetegn a, e, f, g vælger mange implementeringer at kollapse mest i den samme parser. Microsoft MSVCRT gør det med e, f, g , mens glibc gør det med alle fire.
Sårbarheder
scanf er sårbar over for formatstrengangreb . Der skal udvises stor omhu for at sikre, at formateringsstrengen indeholder begrænsninger for streng- og arraystørrelser. I de fleste tilfælde er inputstrengens størrelse fra en bruger vilkårlig og kan ikke bestemmes, før scanf funktionen udføres. Dette betyder, at anvendelser af %s pladsholdere uden længdespecifikatorer i sagens natur er usikre og kan udnyttes til bufferoverløb . Et andet potentielt problem er at tillade dynamiske formateringsstrenge, for eksempel formateringsstrenge, der er gemt i konfigurationsfiler eller andre brugerstyrede filer. I dette tilfælde kan den tilladte inputlængde for strengstørrelser ikke angives, medmindre formateringsstrengen kontrolleres på forhånd, og begrænsninger håndhæves. Relateret til dette er yderligere eller uoverensstemmende formateringspladsholdere, der ikke matcher den aktuelle vararg- liste. Disse pladsholdere kan delvis udvindes fra stakken eller indeholde uønskede eller endda usikre markører, afhængigt af den særlige implementering af varargs .
Se også
Referencer
eksterne links
- - Systemgrænsefladesreference, den eneste UNIX-specifikation , udgave 7 fra The Open Group
- C ++ reference for
std::scanf