]SCANF #përfshi
Sa bukur kur jepen të gjitha të dhënat, dhe asgjë nuk duhet të futet. Por më besoni, pothuajse kurrë nuk është kështu. Mos harroni shkollën kur keni matur disa gjëra dhe më pas keni futur vlerat e marra në formulat e nevojshme.
scanf
Në gjuhën C, përveç funksionit të daljes printf, ekziston edhe funksioni i skanimit për të dhëna. Këtu është funksioni i skanimit që tani do të shqyrtojmë më në detaje:
int i;
scanf("%d", &i);
Duket shumë e ngjashme me funksionin printf. Ekziston edhe në citate të dyfishta specifikuesi i formatit, por ndryshimi është vetëm në pjesën e dytë të funksionit. Kushtojini vëmendje pamjes së shenjës (&)? Pra, kjo shenjë nënkupton marrjen e adresës. Më lejoni të shpjegoj pse kjo është e nevojshme.
Vlerën e futur duhet ta shkruajmë jo diku aty, por pikërisht në adresën ku ndodhet ndryshorja jonë. ato. pa shenjën (&), vlera jonë e futur do të bjerë në të gjitha vendet, përveç atij që na nevojitet. Prandaj, sa herë që ju duhet të vendosni vlera nga tastiera, paraprini variablin me një shenjë adrese (&).
Specifikimi i formatit
Epo tani le të kalojmë specifikuesit e formatit:- %d - lexoni një numër të plotë
- %o - lexo numër oktal
- %x - lexoni numrin heksadecimal
- %e(%f) - lexoni numrin real
- %s - karakter i lexuar
- %s - rreshti i leximit
int i;
scanf("%d", &i);
int i;
scanf("%o", &i);
int i;
scanf("%x", &i);
floatt;
scanf("%f", &t);
charch;
scanf("%c", &ch);
char*str;;
scanf("%s",str);
Mos u thelloni ende në punën me vargje. Pse nuk ka shenjë adrese? Ne do ta shqyrtojmë këtë temë pak më vonë.
Operacionet e krahasimit
Kompjuteri ishte fillimisht logjika boolean, d.m.th. gjithçka është ndërtuar në 0 dhe 1. Nëse nuk e kuptoni se për çfarë bëhet fjalë, atëherë rishikoni filmin The Matrix, ku secili screensaver i gjelbër përbëhej nga këta dy numra magjikë.
Natyrisht, 0 dhe 1 janë të mira, por ne kemi nevojë për një kuptim logjik, kështu që brenda operacionet logjike 0 është FALSE dhe 1 është E VËRTETË. Këto koncepte të TRUE dhe FALSE janë të lidhura ngushtë me operacionet e krahasimit. Për të filluar, ne paraqesim të gjitha llojet e operacioneve të krahasimit:
Në thelb, gabimi më i zakonshëm që bëjnë fillestarët është ngatërrimi me operatorin e caktimit (=). operacion krahasimi(==). Këto janë gjëra krejtësisht të ndryshme. Por në fillim të kodimit, të gjithë kanë gabime mbi këtë bazë, prandaj kini kujdes.
Funksionet printf() dhe scanf() na japin mundësinë për të ndërvepruar me programin. Ne i quajmë funksione I/O. Këto nuk janë funksionet e vetme që mund të përdorim për të futur dhe nxjerrë të dhëna me programet C, por janë më të gjithanshëm. Këto funksione përfshihen në përshkrimin e gjuhës C dhe ato janë dhënë në bibliotekën stdio.h. Në përgjithësi, funksionet printf() dhe scanf() punojnë në të njëjtën mënyrë - secili përdor një varg kontrolli dhe një listë argumentesh. Fillimisht do të shikojmë printf() dhe më pas scanf().
Formati |
Lloji i informacionit të daljes |
numër i plotë dhjetor |
|
një personazh |
|
varg karakteresh |
|
shënimi eksponencial |
|
noton, shënim dhjetor |
|
përdoret në vend të shkrimit %f ose %e |
|
numër i plotë dhjetor i panënshkruar |
|
numër i plotë oktal i panënshkruar |
|
numër i plotë heksadecimal i panënshkruar |
Udhëzimet që i kalohen funksionit printf() kur duam të printojmë disa ndryshore varen nga lloji i variablit. Për shembull, kur shtypni një numër të plotë, formati është %d, dhe kur shtypni një karakter, ai është %c. Formatet janë të renditura në tabelë.
Tani le të shohim se si aplikohen këto forma:
/* vulë */
#përfshi
#define PI 3.14159
numri int = 2003;
printf("Universiteti i Teknologjisë së Informacionit në Internet u hap në vitin %d\n", numri);
printf("Vlera e pi është %f.\n", PI);
Formati i specifikuar kur thirret funksioni printf() është si më poshtë:
printf(Vargu i kontrollit, argumenti1, argumenti2,_);
argumenti 1, argumenti 2, etj. janë parametra të printueshëm të cilët mund të jenë variabla, konstante apo edhe shprehjet llogaritur para printimit.
Vargu i kontrollit është një varg karakteresh që tregon se si duhet të printohen opsionet. Për shembull, në operatori
printf("%d studentë shënuan %f.\n",
vargu i kontrollit është një frazë në thonjëza, dhe numri dhe z janë argumente, ose in këtë rast vlerat e dy variablave.
Ne shohim se linja e kontrollit përmban dy lloje të ndryshme informacioni:
Personazhe të shtypura me tekst.
Identifikuesit e të dhënave, të quajtur gjithashtu specifikimet e konvertimit .
Çdo argument në listën pas vijës së kontrollit duhet të përputhet me një specifikimet e konvertimit. Nëse keni nevojë të printoni ndonjë frazë, atëherë nuk ka nevojë të përdorni specifikimet e konvertimit; nëse ju duhet vetëm të printoni të dhëna, atëherë mund të bëni pa përdorur një koment. Prandaj, secila prej operatorët më poshtë është krejtësisht e pranueshme:
printf("Ky libër nuk është shumë i shtrenjtë!\n");
printf("%c%d\n","$",kosto);
Nëse ju duhet të printoni vetë karakterin %, atëherë përpiluesi do ta marrë atë si një gabim specifikimet e konvertimit. Mënyra për të dalë nga kjo situatë është një zgjidhje mjaft e thjeshtë - të shkruani dy% karaktere me radhë.
Për shembull:
printf("Vetëm %d%% e popullsisë mund të mësojë vetë! \n",i);
Rezultati i programit do të duket si ky:
Vetëm 5% e popullsisë është në gjendje të studiojë në mënyrë të pavarur!
Mund të zgjerojmë përkufizimin bazë specifikimet e konvertimit, duke vendosur modifikues midis shenjës % dhe karakterit që specifikon llojin e konvertimit. Kur përdorni disa modifikues në të njëjtën kohë, ato duhet të specifikohen në rendin në të cilin janë renditur në tabelë.
Modifikuesit |
Kuptimi |
Argumenti do të printohet nga pozicioni i majtë i fushës gjerësia e dhënë. Normalisht, printimi i një argumenti përfundon në pozicionin më të djathtë të fushës. Shembull: %-10 |
|
varg numrash |
Vendos gjerësinë minimale të fushës. Një fushë më e madhe do të përdoret nëse numri ose vargu i printuar nuk përshtatet në fushën origjinale Shembull: %4d |
varg numrash |
Përcakton saktësinë: për llojet e të dhënave me pikë lundruese, numrin e shifrave për të printuar në të djathtë të pikës dhjetore; për vargjet e karaktereve - numri maksimal Shembull i karaktereve të printueshme: %4.2f (dy shifra dhjetore për një fushë me katër karaktere) |
Elementi përkatës i të dhënave ka lloji i gjatë, jo int Shembull: %ld |
printf("/%d/\n",135);
printf("/%2d/\n",135);
printf("/%10d/\n",135);
printf("/%-10d/\n",135);
Së pari specifikimet e konvertimit%d nuk përmban modifikues. Kjo është e ashtuquajtura zgjedhja e paracaktuar, pra rezultati i veprimit të përpiluesit nëse nuk i keni dhënë ndonjë udhëzim shtesë. Së dyti specifikimet e konvertimit- %2d. Ai specifikon që gjerësia e fushës duhet të jetë 2, por meqenëse numri është tre shifror, fusha zgjerohet automatikisht në madhësinë e duhur. Tjetra Specifikim%10d tregon se gjerësia e fushës është 10. E fundit Specifikim%-10d gjithashtu specifikon një gjerësi të fushës prej 10, dhe a - bën që i gjithë numri të zhvendoset majtas.
Funksioni scanf() është një procedurë hyrëse Qëllimi i përgjithshëm A që lexon të dhëna nga stdin stream. Mund të lexojë të dhënat e të gjithëve llojet e bazës dhe i konverton automatikisht në formatin e brendshëm të dëshiruar. Nëse printf() kryente hyrje dhe jo dalje, ai mund të quhet analog i scanf().
Vargu i kontrollit i treguar sipas formatit përbëhet nga tre lloje karakteresh:
- Specifikimi i formatit
- Simbole të veçanta
- Personazhe të tjerë (jo të veçantë)
Përcaktuesit e formatit ndjekin shenjën e përqindjes dhe i tregojnë scanf() se çfarë lloji të të dhënave të lexoni më pas. Kodet e specifikuesve janë dhënë në tabelë.
Kodi | Kuptimi |
---|---|
%Me | Numëroni një personazh |
%d | |
%i | Numëroni numër dhjetor tip numër i plotë |
%e | |
%f | Numëroni numrin me pikë lundruese |
%g | Numëroni numrin me pikë lundruese |
% rreth | Numëroni numrin oktal |
%s | Lexoni rreshtin |
%X | Numëroni numrin heksadecimal |
%R | lexoni treguesin |
%n | Merr një vlerë të plotë të barabartë me numrin e karaktereve të lexuara deri më tani |
%u | Lexon një numër të plotë të panënshkruar |
% | Kërkon një grup karakteresh |
%% | Lexon karakterin % |
Për shembull, %s lexon një varg dhe %d lexon një ndryshore numër të plotë.
Vargu i formatit lexohet nga e majta në të djathtë, duke krahasuar kodet e formatit me argumentet në listën e argumenteve.
Karakteret speciale në vargun e kontrollit bëjnë që scanf() të kapërcejë një ose më shumë personazhe të veçanta në rrjedhën hyrëse. Karakteret speciale janë hapësira, skeda ose rreshti i ri. Një karakter i vetëm i veçantë në vargun e kontrollit bën që scanf() të lexojë, pa kujtuar, ndonjë numër (përfshirë zero) të karaktereve të njëpasnjëshme speciale nga rrjedha hyrëse derisa të ndeshet me një karakter që nuk është karakter i veçantë.
Disponueshmëria karakter të rregullt bën që scanf() të lexojë dhe të heqë karakterin përkatës. Për shembull, "%d,%d" bën që scanf() të lexojë një numër të plotë, të lexojë dhe të heqë presjen dhe më pas të lexojë një numër tjetër të plotë. Nëse karakteri i specifikuar nuk gjendet në rrjedhën hyrëse, scanf() ndalon.
Të gjitha variablat e përdorur për të marrë vlera duke përdorur funksionin scanf() duhet të kërkohen nga adresat e tyre. Kjo do të thotë që të gjitha argumentet e funksionit duhet të jenë tregues drejt variablave. Kështu, C krijon mundësinë e kalimit me referencë, dhe kjo i lejon funksionit të ndryshojë përmbajtjen e argumentit.
scanf("%d", &count);
Vargjet lexohen në vargje karakteresh, dhe emri i grupit, pa asnjë tregues, është adresa e elementit të parë të grupit. Prandaj, për të lexuar një varg në grupin e karaktereve të adresës, mund të përdorni komandën
scanf("%s", adresa);
Në këtë rast, adresa e emrit është tashmë një tregues dhe nuk ka nevojë për prefiksin &.
Artikujt e hyrjes duhet të ndahen me hapësira, skeda ose rreshta të rinj.
Shenjat e pikësimit si presja, pikëpresja etj., nuk konsiderohen ndarëse. Kjo do të thotë se për operatorin
Scanf("%d%d", &r, &c);
Sekuenca 10 20 do të pranohet, por sekuenca 10,20 jo. Specifikimi i formatit scanf() janë në të njëjtin rend si variablat në listën e argumenteve, të cilave u caktohen vlerat e variablave të marra.
Një * i vendosur pas % dhe përpara një specifikuesi të formatit lexon të dhëna të llojit të specifikuar, por e shtyp caktimin. Kështu kodi
Scanf("%d%*c%d", &x, &y);
Futja e sekuencës 10/20 cakton vlerën 10 në x, hedh poshtë / dhe cakton vlerën 20 në y.
Komandat e formatimit mund të specifikojnë një modifikues gjerësia maksimale fusha. Është një numër i plotë që vendoset midis shenjës % dhe specifikuesit të formatit. Kufizon numrin e karaktereve të lexuara për çdo fushë. Për shembull, nëse dëshironi të lexoni jo më shumë se 20 karaktere në grupin e adresave, do të shkruani
Scanf("%20s", adresa);
Nëse transmetimi i hyrjes përmbante më shumë se 20 karaktere, atëherë herën tjetër që të thirret funksioni i hyrjes, ai do të fillojë hyrjen nga pika ku hyrja u ndal gjatë thirrjes aktuale. Hyrja e një fushe mund të ndërpritet përpara se të arrihet gjatësia maksimale fushat nëse ka hapësirë. Në këtë rast, scanf() kalon në fushën tjetër.
Megjithëse hapësirat, skedat dhe vijat e reja përdoren si ndarës të fushave, ato lexohen si çdo karakter tjetër kur futet një karakter i vetëm. Për shembull, duke pasur parasysh rrjedhën hyrëse x y, funksioni
Scanf("%s%s%s", &a, &b, &c);
Vendosni karakterin x në ndryshoren a, hapësirën në ndryshoren b dhe y në ndryshoren c.
Kini kujdes: çdo karakter tjetër në vargun e kontrollit - duke përfshirë hapësirat, skedat dhe rreshtat e rinj - përdoren për të specifikuar dhe hequr karakteret nga rrjedha e hyrjes. Për shembull, me një rrymë hyrëse prej 10t20, funksioni
Scanf("%st%s", &x, &y);
Vendos 10 në x dhe 20 në y. Karakteri t do të hidhet poshtë sepse ka një t në vargun e kontrollit.
Një veçori tjetër e funksionit scanf() quhet grup skanimi. Seti i skanimit përcakton karakteret që do të lexohen nga funksioni scanf() dhe do t'u caktohen elementeve të grupit përkatës të karaktereve. Për të specifikuar një grup skanimi, karakteret hyrja e të cilave është e vlefshme duhet të vendosen në kllapa katrore. Përpara të parës kllapa katrore vendosni shenjën e përqindjes. Për shembull, lista e mëposhtme e grupeve të skanimit bën që scanf() të lexojë vetëm karakteret A, B dhe C:
Argumenti përkatës i listës së grupeve të skanimit duhet të jetë një tregues në një grup karakteresh. Kur përdorni një grup skanimi, funksioni scanf() lexon karakteret dhe i vendos ato në grupin e specifikuar derisa të ndeshet me një karakter që nuk është në grupin e skanimit (d.m.th., lexohen vetëm karakteret në grupin e skanimit).
Vargu i kthyer nga scanf() do të përmbajë një varg të përfunduar me null. Lista e karaktereve që duhen lexuar mund të specifikohet edhe në formë të kundërt. Për ta bërë këtë, vendosni ^ si karakterin e parë. Pastaj scanf() do të pranojë çdo karakter që nuk përfshihet në grupin e skanimit.
Duke përdorur thonjëza, mund të specifikoni gamën e karaktereve të pranuara. Për shembull, shprehja e mëposhtme i thotë scanf() të pranojë shkronjat "A" deri në "Z":
Seti i skanimit bën dallimin midis shkronjave të mëdha dhe shkronja të vogla. Nëse dëshironi që scanf() t'i pranojë të dyja, duhet t'i listoni veçmas në grupin e skanimit.
Funksioni scanf() kthen një numër të barabartë me numrin e fushave vlerat e të cilave u janë caktuar në të vërtetë variablave. Ky numër nuk përfshin fushat që janë lexuar, por vlerat e tyre nuk janë caktuar për asgjë për shkak të përdorimit të modifikuesit * për të shtypur detyrën. Nëse ka ndodhur një gabim përpara se të caktohet vlera e fushës së parë, EOF kthehet.
Kur përdorni Borland C++ në një mjedis 16-bitësh, mund të ndryshoni modelin e paracaktuar të memories që përdoret për të përpiluar një program duke tregues i qartë madhësia e çdo treguesi të përdorur në thirrjen scanf(). Treguesi i afërt specifikohet nga modifikuesi N dhe treguesi larg nga modifikuesi F. (Nuk mund të përdorni modifikuesin N nëse programi është kompiluar për modelin e memories së madhe.)
Funksioni scanf() është një funksion me shumë qëllime që ju lejon të futni çdo lloj të dhënash në kompjuter. Emri i funksionit pasqyron qëllimin e tij - funksioni skanon (shikon) tastierën, përcakton se cilët butona shtypen dhe më pas interpreton hyrjen bazuar në karakteret e formatuara SCAN. Ashtu si funksioni printf(), scanf() mund të marrë shumë argumente, duke lejuar kështu që vlerat e variablave numerike, karaktere dhe vargje të futen në të njëjtën kohë.
Ashtu si lista e parametrave printf(), edhe lista e parametrave të funksionit scanf() përbëhet nga dy pjesë: një varg formati dhe një listë të dhënash (Figura 5.7). Vargu i formatit përmban specifikues të formatit, këtu ata quhen konvertuesit e karaktereve* të cilat përcaktojnë se si duhet të interpretohet hyrja. Lista e të dhënave përmban variablat në të cilat duhet të futen vlerat hyrëse.
Oriz. 5.7. Lista e parametrave të funksionit scanf() është e ndarë në dy pjesë
Specifikimi i formatit janë të ngjashëm me ato të përdorura nga funksioni printf():
Kur futni të dhëna numerike ose karakteresh, duhet të specifikoni adresën e ndryshores në listën e të dhënave të funksionit scanf(), dhe jo vetëm emrin e saj:
scanf("%f", &amount);
* ATorigjinalekarakteret e konvertimit.(Shënim përkth.)
Në këtë shembull, funksioni scanf() fut një numër me pikë lundruese dhe e ruan atë në zonën e kujtesës të rezervuar për variablin sasi. Sapo një numër vendoset në këtë zonë të memories, ai automatikisht bëhet vlera e ndryshores.
Ndërsa funksioni scanf() po ekzekutohet, ekzekutimi i programit pezullohet dhe programi është në pritje të hyrjes. Hyrja përfundon me një goditje tasti Hyni.
Parimi i punës me të dhënat e funksionit scanf() është thelbësisht i ndryshëm nga puna e funksioneve gets() dhe getchar(). Për të kuptuar saktësisht se çfarë ndodh kur hyni me scanf(), duhet t'i shikoni këto ndryshime në detaje.
rrymë hyrëse
Kur të dhënat futen duke përdorur funksionin gets(), të gjithë karakteret që janë shtypur në tastierë përpara se të shtypet Hyni, bëhet vlera e ndryshores. Kur një karakter futet duke përdorur funksionin getchar(), shtypja e tastit shkakton automatikisht caktimin e karakterit përkatës në ndryshore.
Funksioni scanf() funksionon ndryshe. Në vend që thjesht të marrë të dhënat dhe t'i caktojë ato në një ndryshore, scanf() kryesisht përdor specifikuesit e formatit për të përcaktuar se si duhet të trajtohen karakteret hyrëse.
Është e zakonshme të thuhet se scanf() merr të dhëna nga rrymë hyrëse. Një rrjedhë hyrëse është një sekuencë karakteresh që vijnë nga një burim. Në rastin e funksionit scanf(), burimi është tastiera. Pasi të keni shtypur tastin Hyni të gjitha të dhënat që janë futur deri tani i kalohen scanf() si një grup karakteresh ende pa kuptim, në të njëjtin rend në të cilin janë shtypur. scanf() më pas përcakton se cilat karaktere përputhen me llojin e specifikuar nga specifikuesi i formatit dhe cilët duhet të injorohen. Përcaktuesit e formatit quhen konvertues të karaktereve sepse marrin karaktere të papërpunuara nga rryma hyrëse dhe i konvertojnë ato në të dhëna të një lloji specifik. Figura 5.8 ilustron këtë proces.
Funksioni scanf() injoron karakteret jo-informative: hapësirat, skedat, rreshtat e rinj, përveç nëse lloji aktual i të dhënave është char. Konsideroni programin:
puts("Ju lutemi shkruani një numër: ");
scanf("%d", &count);
printf("Numri është %d", count);
Oriz. 5.8. Funksioni scanf() lexon rrjedhën hyrëse dhe përcakton se cilat të dhëna duhet të futen dhe cilat duhet të injorohen.
Përpara se të futni një numër, mund të shtypni shiritin e hapësirës sa të dëshironi - C do të injorojë hapësirat, duke pritur për karakterin e parë domethënës. C më pas do të përpiqet të konvertojë karakteret sipas specifikuesve të formatit në vargun e formatit scanf(). Nëse këto karaktere përputhen me formatin (në këtë rast, nëse janë numra), ato do të futen në ndryshore. Futja e të dhënave do të ndalet nëse haset një karakter që nuk përputhet me formatin e pritur, pra nuk është një shifër. Për shembull, nëse shkruani sekuencën "123abc" në tastierë, atëherë numri 123 në shembullin tonë do t'i caktohet variablit count dhe shkronjat "abc" do të shpërfillen, siç tregohet në figurën 5.9. Një hapësirë mund të shkaktojë ndalimin e futjes së të dhënave. Për shembull, nëse shkruani "123", ndryshores do t'i caktohet vlera 12 dhe numri 3 do të shpërfillet.
Oriz. 5.9. Funksioni scanf() ndalon futjen e të dhënave kur ndeshet me karakterin e parë jonumerik.
Karakteri i parë domethënës duhet të përputhet me formatin e specifikuar në argumentin e funksionit scanf(). Pra, nëse shkruani sekuencën "ABC123", programi do ta injorojë atë plotësisht dhe ju do të mbeteni në errësirë për vlerën e ndryshores.
Cilat karaktere i konsideron programi "të përshtatshëm" varet nga specifikuesit e formatit. Nëse treguesi është %d, atëherë vetëm shifrat dhe shenja minus janë "të përshtatshme". Nëse vendosni treguesin %x, atëherë karakteret që korrespondojnë me formatin do të jenë 0123456789ABCDE, pasi të gjithë përdoren kur shkruani numra në sistemin heksadecimal të numrave. Nëse treguesi është %c, çdo karakter pranohet, madje edhe hapësira brenda rrymës hyrëse, funksioni scanf () nuk e injoron në këtë rast. Nëse shkruani udhëzime:
scanf("%c", &shkronjë);
dhe shtypni shiritin e hapësirës në fillim të sekuencës personazhe domethënëse, scanf() do ta vendosë variablin në një hapësirë, duke injoruar karakteret pasuese. Prandaj, kur keni të bëni me llojin char, nuk mund të vendosni hapësira përpara karaktereve të tjera.
Duke pasur parasysh një varg, funksioni scanf() do të fillojë caktimin e tij në karakterin e parë domethënës, duke injoruar hapësirat kryesore dhe do të ndalojë caktimin kur të ndeshet me hapësirën e parë të karakterit të rëndësishëm. Hidhini një sy programit:
puts("Ju lutemi shkruani emrin tuaj: ");
scanf("%s", emri);
Vini re se operatori i adresës get nuk përdoret me një emër të variablit të vargut. Nëse shkruani "Nancy" në tastierën tuaj dhe shtypni Enter, ato karaktere do t'i caktohen ndryshores së emrit. Edhe nëse shkruani "Nancy Chasin", scanf() do të fillojë të caktojë karaktere në karakterin e parë domethënës dhe do të ndalet në hapësirën e parë, kështu që vetëm emri i Nancy do të bëhet vlera e ndryshores dhe programi do të injorojë pjesën tjetër (Fig. 5.10).
Oriz. 5.10. Funksioni scanf() ndalon leximin e karaktereve në një varg kur shfaqet hapësira e parë.
Për shkak të kësaj veçorie të funksionit scanf(), nuk është shumë i përshtatshëm për futjen e vargjeve. Në këto raste është më mirë të përdoret funksioni gets().