] SCANF #include
Kako je dobro kada su svi podaci dati, a ništa ne treba unositi. Ali, vjerujte mi, to se praktično ne dešava. Sjetite se škole, kada ste mjerili određene stvari, a zatim ste dobivene vrijednosti ubacivali u potrebne formule.
scanf
U jeziku C, pored printf izlazne funkcije, postoji i scanf funkcija za unos. Evo scanf funkcije upravo sada i mi ćemo detaljnije pogledati:
int i;
scanf ("% d", & i);
Izgleda vrlo slično funkciji printf. Također dostupno u dvostruki navodnici specifikacija formata, ali razlika je u drugom dijelu funkcije. Primijetili ste pojavu znaka (&)? Dakle, ovaj znak znači uzimanje adrese. Odmah ću objasniti zašto je to potrebno.
Unesenu vrijednost moramo napisati ne negdje tamo, već tačno na adresi na kojoj se nalazi naša varijabla. One. unsigned (&) naša unesena vrijednost će ići na sva mjesta osim na ono što nam je potrebno. Stoga, kad god trebate unijeti vrijednosti sa tastature, stavite znak adrese (&) ispred varijable.
Specifikatori formata
Pa sad idemo preko specifikacije formata:- % d - čitanje cijelog broja
- % o - čitanje oktalni broj
- % x - čitanje heksadecimalnog broja
- % e (% f) - čitanje realnog broja
- % s - čitanje karaktera
- % s - red za čitanje
int i;
scanf ("% d", & i);
int i;
scanf ("% o", & i);
int i;
scanf ("% x", & i);
float t;
scanf ("% f", & t);
char ch;
scanf ("% c", & ch);
char * str ;;
scanf ("% s", str);
Nemojte se još baviti radom sa žicama. Zašto nema znakova preuzimanja adrese? Ovu temu ćemo razmotriti malo kasnije.
Operacije poređenja
Računar je prvobitno instaliran boolean logika, tj. sve je izgrađeno na 0 i 1. Ako ne razumijete o čemu se radi, onda pogledajte film Matrix, gdje se svaki zeleni screen saver sastoji samo od ova dva magična broja.
Naravno, 0 i 1 su dobri, ali nam je potreban logički smisao, dakle logičke operacije 0 je LAŽ, a 1 je TAČNO. Ovi koncepti TAČNO i LAŽNO su usko povezani operacije poređenja... Za početak, evo svih vrsta operacija poređenja:
U osnovi, najčešća greška koju prave početnici je da pomiješaju operaciju dodjele (=). operacija poređenja(==). To su potpuno različite stvari. Ali na početku kodiranja svi imaju greške baš po ovoj osnovi, stoga budite oprezni.
Funkcije printf () i scanf () nam daju mogućnost interakcije s programom. Zovemo ih I/O funkcijama. Ovo nisu jedine funkcije koje možemo koristiti za unos i izlaz podataka u C programima, ali su najsvestranije. Ove funkcije su uključene u opis jezika C i date su u biblioteci stdio.h. Tipično, printf () i scanf () rade na isti način - svaki koristi kontrolni niz i listu argumenata. Prvo ćemo pogledati kako printf () radi, a zatim scanf ().
Format |
Tip prikazane informacije |
decimalni cijeli broj |
|
jedan lik |
|
niz znakova |
|
eksponencijalna notacija |
|
broj s pomičnim zarezom, decimalni zapis |
|
koristi se umjesto% f ili% e |
|
neoznačeni decimalni cijeli broj |
|
neoznačeni oktalni cijeli broj |
|
heksadecimalni cijeli broj bez predznaka |
Instrukcije koje se daju printf () kada želimo da ispišemo neku varijablu zavise od toga koji tip te varijable. Na primjer, kada se ispisuje cijeli broj, format je% d, a kada se ispisuje znak, to je% c. Formati su navedeni u tabeli.
Sada da vidimo kako se ovi oblici primjenjuju:
/* pečat */
#include
#define PI 3.14159
int broj = 2003;
printf ("Internet univerzitet informacionih tehnologija otvoren u% d godine \ n", broj);
printf ("Vrijednost pi je% f. \ n", PI);
Format naveden prilikom poziva funkcije printf () je sljedeći:
printf (Kontrolni niz, arg1, arg2, _);
argument 1, argument 2, itd. su parametri za štampanje, koji mogu biti varijable, konstante ili čak izrazi izračunato prije štampanja.
Kontrolni niz je niz znakova koji označava kako bi se parametri trebali ispisati. Na primjer, u operater
printf ("% d učenika je ocijenjeno% f. \ n",
kontrolni niz je fraza pod navodnicima, a broj i z su argumenti ili in u ovom slučaju vrijednosti dvije varijable.
Vidimo da kontrolna linija sadrži dvije različite vrste informacija:
Znakovi štampani tekstualno.
Identifikatori podataka, tzv specifikacije konverzije .
Svaki argument sa liste nakon kontrolnog niza mora imati jedan specifikacija konverzije... Ako trebate odštampati bilo koju frazu, onda nema potrebe za korištenjem specifikacija konverzije; ako trebate samo ispisati podatke, možete i bez korištenja komentara. Stoga, svaki od operateri u nastavku su potpuno prihvatljivi:
printf ("Ova knjiga nije jako skupa! \ n");
printf ("% c% d \ n", "$", cijena);
Ako trebate odštampati sam simbol %, kompajler će ga zamijeniti kao grešku specifikacija konverzije... Izlaz iz ove situacije je prilično jednostavno rješenje - upišite dva% znakova za redom.
Na primjer:
printf ("Samo % d %% populacije može samostalno učiti! \ n", i);
Rezultat programa će izgledati ovako:
Samo 5% stanovništva može samostalno da studira!
Možemo proširiti osnovnu definiciju specifikacije konverzije postavljanjem modifikatora između znaka % i znaka koji specificira tip konverzije. Kada koristite više modifikatora u isto vrijeme, oni moraju biti navedeni redoslijedom kojim su navedeni u tabeli.
Modifikatori |
Značenje |
Argument će biti ispisan sa pozicije lijeve margine zadata širina... Obično se štampanje argumenta završava na krajnjoj desnoj poziciji margine. Primjer:% -10 |
|
niz brojeva |
Određuje minimalnu širinu polja. Veće polje će se koristiti ako odštampani broj ili linija ne stane u originalno polje Primer:% 4d |
niz brojeva |
Određuje preciznost: za tipove podataka s pomičnim zarezom, broj cifara koje treba odštampati desno od decimalnog zareza; za nizove znakova - maksimalan broj znakova za ispis Primjer: % 4.2f (dvije decimalne cifre za polje od četiri znaka) |
Odgovarajuća stavka ima dugačak tip, ne int Primjer:% ld |
printf ("/% d / \ n", 135);
printf ("/% 2d / \ n", 135);
printf ("/% 10d / \ n", 135);
printf ("/% - 10d / \ n", 135);
Prvi specifikacija konverzije% d ne sadrži modifikatore. Ovo je takozvani podrazumevani izbor, odnosno rezultat radnje kompajlera ako mu niste dali nikakve dodatne instrukcije. Drugi specifikacija konverzije-% 2d. Označava da širina polja treba da bude 2, ali pošto se broj sastoji od tri znamenke, polje se automatski proširuje na potrebnu veličinu. Sljedeći specifikacija% 10d označava širinu polja 10. Zadnje specifikacija% -10d također označava širinu polja od 10, a znak - uzrokuje pomak cijelog broja ulijevo.
Funkcija scanf () je rutina unosa opće namjene koji čita podatke iz stdin toka. Ona može pročitati podatke svih osnovne vrste i automatski ih konvertuje u željeni interni format. Ako je printf () vršio unos umjesto izlaza, mogao bi se nazvati analogom scanf ().
Kontrolni niz na koji ukazuje format sastoji se od tri vrste znakova:
- Specifikatori formata
- Posebni simboli
- Ostali znakovi (nisu posebni)
Specifikatori formata prate znak postotka i govore scanf-u () koju vrstu podataka da čita sljedeće. Kodovi specifikacija su prikazani u tabeli.
Šifra | Značenje |
---|---|
%Sa | Brojite jedan znak |
% d | |
% i | Razmislite decimalni broj ceo tip |
% e | |
% f | Pročitajte broj u pokretnom zarezu |
% g | Pročitajte broj u pokretnom zarezu |
%O | Brojite oktalni broj |
% s | Pročitaj liniju |
%X | Pročitaj heksadecimalni broj |
%R | Pokazivač čitanja |
% n | Prihvata cjelobrojnu vrijednost jednaku broju znakova pročitanih do trenutnog trenutka |
% u | Čita cijeli broj bez predznaka |
% | Traži skup znakova |
%% | Čita % znak |
Na primjer, % s čita string, a % d čita cjelobrojnu varijablu.
Niz formata se čita s lijeva na desno, mapirajući između kodova formata i argumenata iz liste argumenata.
Posebni znakovi u kontrolnom nizu uzrokuju da scanf () preskoči jedan ili više njih specijalni znakovi u ulaznom toku. Posebni znakovi su razmak, tabulator ili novi red. Jedan specijalni znak na kontrolnoj liniji uzrokuje da scanf () čita, bez pamćenja, bilo koji broj (uključujući nulu) uzastopnih specijalnih znakova iz ulaznog toka, sve dok se ne naiđe na nespecijalni znak.
Dostupnost regularnog karaktera uzrokuje da scanf () pročita i odbaci odgovarajući znak. Na primjer, "% d,% d" uzrokuje da scanf () pročita cijeli broj, pročita i odbaci zarez, a zatim pročita drugi cijeli broj. Ako se navedeni znak ne pronađe u ulaznom toku, scanf () se zaustavlja.
Sve varijable koje se koriste za primanje vrijednosti pomoću funkcije scanf () moraju se tražiti po njihovim adresama. To znači da svi argumenti funkcije moraju biti pokazivači na varijable. Dakle, C omogućava prolazak po referenci, a to omogućava funkciji da promijeni sadržaj argumenta.
Scanf ("% d", & count);
Nizovi se čitaju u nizove znakova, a ime niza, bez ikakvog pokazivača, je adresa prvog elementa u nizu. Stoga, da biste pročitali string u nizu znakova adrese, možete koristiti naredbu
Scanf ("% s", adresa);
U ovom slučaju, adresa imena je već pokazivač i ne treba prefiks &.
Stavke ulaznih podataka moraju biti odvojene razmacima, tabulatorima ili novim redovima.
Znakovi interpunkcije kao što su zarez, tačka i zarez, itd. ne smatraju se graničnicima. To znači da za operatera
Scanf ("% d% d", & r, & c);
Slijed 10 20 će biti prihvaćen, ali sekvenca 10.20 neće. Specifikatori formata scanf () su u istom redoslijedu kao i varijable u listi argumenata kojima su dodijeljene vrijednosti primljenih varijabli.
* iza% i prije specifikacija formata čita podatke navedenog tipa, ali potiskuje dodjelu. Dakle, kod
Scanf ("% d% * c% d", & x, & y);
Kada unesete sekvencu, 10/20 dodjeljuje 10 x, odbacuje / i dodjeljuje 20 y.
Naredbe za formatiranje mogu postaviti modifikator maksimalna širina polja. To je cijeli broj koji se nalazi između znaka % i specifikacije formata. Ograničava broj pročitanih znakova za bilo koje polje. Na primjer, ako trebate pročitati ne više od 20 znakova u adresni niz, napisali biste
Scanf ("% 20s", adresa);
Ako ulazni tok sadrži više od 20 znakova, tada će u sljedećem pozivu funkcija unosa započeti unos od tačke na kojoj je unos zaustavljen tokom trenutnog poziva. Unos polja se može prekinuti prije dostizanja maksimalna dužina polja ako se naiđe na razmak. U ovom slučaju scanf () prelazi na sljedeće polje.
Iako se razmaci, tabulatori i novi redovi koriste kao separatori polja, oni se čitaju kao i svaki drugi znak kada se unese jedan znak. Na primjer, dat je ulazni tok x y, funkcija
Scanf ("% c% c% c", & a, & b, & c);
Staviće znak x u promenljivu a, razmak - u promenljivu b i y - u promenljivu c.
Budite oprezni: svi drugi znakovi u kontrolnoj liniji — uključujući razmake, tabulatore i nove redove — koriste se za specificiranje i uklanjanje znakova iz ulaznog toka. Na primjer, za ulazni tok od 10t20, funkcija
Scanf ("% st% s", & x, & y);
Mjesta 10 u x i 20 u y. t će biti odbačen jer postoji t u kontrolnoj liniji.
Još jedna karakteristika funkcije scanf () naziva se višestruko skeniranje. Skup za skeniranje definira znakove koje će čitati funkcija scanf () i dodijeliti elementima odgovarajućeg niza znakova. Da biste odredili skup skeniranja, morate staviti znakove koji su važeći u uglaste zagrade. Prije prvog uglata zagrada stavlja se znak procenta. Na primjer, sljedeća lista skupova skeniranja navodi da scanf () čita samo znakove A, B i C:
Argument koji odgovara listi skupa skeniranja mora biti pokazivač na niz znakova. Kada koristite višestruko skeniranje, funkcija scanf () čita znakove i postavlja ih u navedeni niz sve dok se ne naiđe na znak koji nije uključen u skup skeniranja (to jest, čitaju se samo znakovi uključeni u skup za skeniranje).
Niz koji vraća scanf () će sadržavati niz završen nultom. Lista čitljivih simbola također se može postaviti u inverznom obliku. Da biste to učinili, postavite ^ kao prvi znak. Tada će scanf () prihvatiti bilo koji karakter koji nije uključen u set za skeniranje.
Koristeći navodnike, možete odrediti raspon znakova koji će se tumačiti. Na primjer, sljedeći izraz upućuje scanf () da prihvati slova od A do Z:
Višestruka skeniranja razlikuju velika slova i mala slova... Ako želite da scanf () prihvati oba, morate ih navesti zasebno u skupu skeniranja.
Funkcija scanf () vraća broj jednak broju polja čije su vrijednosti zapravo dodijeljene varijablama. Ovaj broj ne uključuje polja koja su pročitana, ali njihove vrijednosti nisu dodijeljene ničemu zbog upotrebe modifikatora * za potiskivanje dodjele. Ako dođe do greške prije dodjeljivanja vrijednosti prvom polju, vraća se EOF.
Kada koristite Borland C++ u 16-bitnom okruženju, možete promijeniti zadani memorijski model za kompajliranje vašeg programa tako što ćete eksplicitna indikacija veličina svakog pokazivača koji se koristi u scanf() pozivu. Bliski pokazivač je specificiran modifikatorom N, a pokazivač udaljenim F modifikatorom (Ne možete koristiti N modifikator ako je program kompajliran za model ogromne memorije.)
Funkcija scanf () je višenamenska funkcija koja vam omogućava da unesete bilo koju vrstu podataka u računar. Naziv funkcije odražava njenu svrhu - funkcija skenira (skenira) tastaturu, određuje koji se tasteri pritisnu, a zatim interpretira unos na osnovu SCAN formatiranih znakova. Baš kao i funkcija printf (), scanf () može uzeti više argumenata, dopuštajući na taj način da se vrijednosti numeričkih, znakovnih i string varijabli unose u isto vrijeme.
Baš kao i lista parametara printf (), lista parametara funkcije scanf () se sastoji od dva dijela: niza formata i liste podataka (slika 5.7). Niz formata sadrži indikatore formata, ovdje se oni nazivaju pretvarači znakova* koji definišu kako treba tumačiti unos. Lista podataka sadrži varijable u koje se moraju unijeti ulazne vrijednosti.
Rice. 5.7. Lista parametara funkcije scanf () podijeljena je na dva dijela.
Pokazivači formata su slični onima koje koristi funkcija printf ():
Prilikom unosa numeričkih ili znakovnih podataka, trebali biste navesti adresu varijable u listi podataka funkcije scanf (), a ne samo njeno ime:
scanf ("% f", & iznos);
* Voriginalznakova za konverziju.(Napomena prev.)
U ovom primjeru, funkcija scanf () uzima broj s pomičnim zarezom i umeće ga u memorijsko područje rezervirano za varijablu iznosa. Čim se broj uklopi u ovo područje memorije, on automatski postaje vrijednost varijable.
Dok je funkcija scanf () pokrenuta, program je suspendovan i program čeka na unos podataka. Unos se završava pritiskom na taster Enter.
Način na koji funkcija scanf () radi s podacima bitno se razlikuje od funkcija gets () i getchar (). Da biste razumjeli šta se tačno dešava kada kucate sa scanf (), morate detaljnije pogledati ove razlike.
Ulazni tok
Kada se podaci unose pomoću funkcije gets (), svi znakovi koji su ukucani na tastaturi prije pritiska Enter, postaje vrijednost varijable. Kada se znak unese pomoću funkcije getchar (), pritiskom na tipku automatski se promjenjivi dodijeli odgovarajući znak.
Funkcija scanf () radi drugačije. Umjesto jednostavnog preuzimanja podataka i dodjeljivanja varijabli, scanf () prvenstveno koristi pokazivače formata da bi odredio kako interpretirati unesene znakove.
Uobičajeno je reći da scanf () prima podatke od ulazni tok... Ulazni tok je niz znakova koji dolaze iz nekog izvora. U slučaju scanf (), izvor je tastatura. Nakon pritiska na tipku Enter svi podaci koji su uneseni do tog trenutka prosljeđuju se funkciji scanf () kao još uvijek besmislen skup znakova, istim redoslijedom kojim su upisani. Scanf () zatim određuje koji znakovi odgovaraju tipu specificiranom u specifikaciji formata, a koje treba zanemariti. Pokazivači formata se nazivaju pretvarači znakova jer uzimaju originalne znakove iz ulaznog toka i pretvaraju ih u podatke određenog tipa. Slika 5.8 ilustruje ovaj proces.
Funkcija scanf () zanemaruje prazne znakove kao što su razmaci, tabulatori, novi redovi, osim ako je trenutni tip podataka char. Razmotrite program:
puts ("Molimo unesite broj:");
scanf ("% d", & count);
printf ("Broj je% d", count);
Rice. 5.8. Funkcija scanf () čita ulazni tok i određuje koje podatke treba unijeti, a koje zanemariti
Prije unosa broja, možete pritisnuti tipku za razmak koliko god želite - C će zanemariti razmake, čekajući prvi značajni znak. Tada će C pokušati pretvoriti znakove u skladu sa specifikacijama formata u nizu formata funkcije scanf (). Ako ti znakovi odgovaraju formatu (u ovom slučaju, ako su brojevi), bit će uneseni u varijablu. Unos podataka će se zaustaviti ako se naiđe na znak koji nije u očekivanom formatu, odnosno nije cifra. Na primjer, ako na tastaturi upišete sekvencu "123abc", tada će broj 123 u našem primjeru biti dodijeljen varijabli count, a slova "abc" će biti zanemarena, kao što je prikazano na slici 5.9. Prazno mjesto može uzrokovati zaustavljanje unosa podataka. Na primjer, ako upišete "123", varijabli će biti dodijeljena vrijednost 12, a broj 3 će biti zanemaren.
Rice. 5.9. Funkcija scanf () zaustavlja unos podataka kada naiđe na prvi nenumerički znak
Prvi značajni znak mora odgovarati formatu navedenom u argumentu funkcije scanf (). Dakle, ako odštampate sekvencu "ABC123", program će je zanemariti u cijelosti, a vi ćete ostati u mraku oko vrijednosti varijable.
Koje znakove program smatra "prikladnim" ovisi o specifikacijama formata. Ako je pokazivač % d, tada su "prikladni" samo brojevi i znak minus. Ako stavite pokazivač% x, tada će znakovi 0123456789ABCDE odgovarati formatu, jer se svi koriste prilikom pisanja brojeva u heksadecimalnom zapisu. Ako je pokazivač% c, prihvataju se svi znakovi, čak ni razmak unutar ulaznog toka ne zanemaruje funkcija scanf (). Ako napišete uputstvo:
scanf ("% c", & slovo);
i pritisnite razmaknicu na početku niza značajni simboli, scanf () će postaviti varijablu na razmak, zanemarujući sljedeće znakove. Stoga, kada radite sa char, ne možete stavljati razmake ispred drugih znakova.
Prilikom unosa stringa, scanf () će početi dodjeljivati vrijednost prvom značajnom znaku, zanemarujući vodeće razmake, i prestati dodjeljivati na prvom značajnom znaku. Pogledajte program:
puts ("Molimo unesite svoje ime:");
scanf ("% s", ime);
Imajte na umu da se operator getter ne koristi sa imenom varijable string. Ako na tastaturi upišete "Nancy" i pritisnete Enter, ovi znakovi će biti dodijeljeni imenu varijable. Čak i ako upišete "Nancy Chesin", scanf () će početi dodjeljivati znakove na prvom značajnom znaku i zaustaviti se na prvom razmaku, tako da će varijabla i dalje biti samo Nancyno ime, a program će zanemariti ostatak (slika 5.10).
Rice. 5.10. Funkcija scanf () zaustavlja čitanje znakova u nizu na prvom razmaku
Zbog ove posebnosti funkcije scanf () nije baš zgodna za unos nizova. U ovim slučajevima, bolje je koristiti funkciju gets ().