- 1 1. Sissejuhatus
- 2 2. Mis on standardne sisend
- 3 3. Standardse sisendi põhitõed C-keeles
- 4 4. Turvaline standardse sisendi kasutamine
- 5 5. Standardse sisendi rakenduslik kasutamine
- 6 6. Levinumad probleemid ja nende lahendused
- 7 7. Näited standardse sisendi kasutamisest
- 8 8. Kokkuvõte
1. Sissejuhatus
C-keelt õppides on kasutaja sisendi käsitlemine ehk “standardne sisend” vältimatu ja väga oluline funktsioon. Standardse sisendi õige mõistmine ja turvaline kasutamine võimaldab oluliselt parandada programmi paindlikkust ja töökindlust.
Selles artiklis selgitame süsteemselt standardse sisendi kasutamist C-keeles – alustades põhialustest ja lõpetades rakenduslike näidetega. Ka algajatele arusaadavuse tagamiseks lisame näidiskoodi, et saaksite õpitut kohe oma programmide arenduses rakendada.
Standardse sisendi olulisus
Standardne sisend on programmide jaoks põhiline mehhanism andmete vastuvõtmiseks väljastpoolt. Seda kasutatakse näiteks järgmistes olukordades:
- Arvutusäpp, mis kasutab kasutaja sisestatud numbreid
- Otsingufunktsioon, mis kasutab tekstistringe
- Dünaamilised programmid, mis reageerivad käsurealt antud käskudele
Sellistes olukordades võimaldab standardse sisendi õige käsitlemine luua tõhusaid ja turvalisi programme.
Mida selles artiklis õpid
Selles artiklis käsitleme järgmisi teemasid:
- Standardse sisendi põhimõte ja selle teostus C-keeles
scanf
jafgets
funktsioonide kasutamine- Kuidas rakendada turvalist ja töökindlat sisendi töötlemist
- Edasijõudnutele mõeldud andmetöötluse tehnikad
- Levinumad probleemid ja nende lahendused
Kellele see artikkel on mõeldud
- Algajad, kes õpivad C-keelt esimest korda
- Programmeerijad, kes ei tunne end kindlalt standardse sisendi kasutamisel
- Need, kes soovivad luua turvalist ja tõhusat sisenditöötlust
2. Mis on standardne sisend
Standardne sisend C-keeles on põhiline mehhanism, mille kaudu programm saab andmeid välisest allikast. See on osa “standardsest sisendist ja väljundist” ning võimaldab kasutajal anda programmile andmeid terminali või käsurea kaudu. Selles jaotises selgitame standardse sisendi põhikontseptsiooni ja rolli.
Standardse sisendi määratlus
Standardne sisend (Standard Input, stdin
) viitab andmevoole, mida programm kasutab andmete vastuvõtmiseks väljastpoolt. C-keeles saab standardset sisendit hõlpsasti kasutada stdio.h
teegi abil.
- Andmeid sisestatakse tavaliselt klaviatuuri kaudu.
- Sisestatud andmeid töödeldakse programmis ning tulemused väljastatakse standardväljundisse.
Standardse sisendi ja väljundi mehhanism
C-keeles on saadaval kolm standardvoogu:
- Standardne sisend (stdin): andmete vastuvõtmiseks väljastpoolt.
- Standardne väljund (stdout): programmide tulemuste väljastamiseks.
- Standardne veaväljund (stderr): veateadete väljastamiseks.
Näide praktilisest toimimisest
Järgmine näide võtab standardse sisendi kaudu arvu ja väljastab selle standardväljundisse.
#include <stdio.h>
int main() {
int number;
printf("Sisesta arv: ");
scanf("%d", &number); // loe täisarv standardse sisendi kaudu
printf("Sisestatud arv on: %d\n", number); // väljasta standardväljundisse
return 0;
}
Standardse sisendi roll ja olulisus
Standardset sisendit kasutatakse järgmistes programmides:
- Andmetöötlusprogrammid: numbrite või tekstistringide sisestamine ja nende põhjal arvutuste või analüüside tegemine.
- Interaktiivsed rakendused: programmi töö muutmine vastavalt kasutaja käskudele.
- Dünaamiline andmete töötlemine: kasutaja sisestatud andmete reaalajas töötlemine.
Standardse sisendi eelised
- Paindlikkus: toetab erinevaid sisendiallikaid, nagu klaviatuur, torud ja ümbersuunamine.
- Lihtsus: sisseehitatud funktsioonide
scanf
jafgets
abil on sisendi töötlemine lihtne.
3. Standardse sisendi põhitõed C-keeles
C-keeles on kasutajal andmete sisestamiseks saadaval mitu funktsiooni. Kõige tavalisemad on scanf
ja fgets
. Selles jaotises selgitame, kuidas kumbagi kasutada koos näidetega.
scanf
funktsiooni kasutamine
scanf
on funktsioon, mis analüüsib sisestatud andmeid vormingutunnuste abil ja salvestab need muutujatesse.
Põhisüntaks
int scanf(const char *format, ...);
format
: määrab andmete vormingu stringina....
: muutujate aadressid, kuhu sisestatud väärtused salvestatakse.
Peamised vormingutunnused
Tunnus | Selgitus | Näide |
---|---|---|
%d | Täisarv | 42 |
%f | Koma-arv (ujukomaarv) | 3.14 |
%c | Üks märk | A |
%s | Sõnestring | Hello |
Kasutusnäide
#include <stdio.h>
int main() {
int age;
printf("Sisesta oma vanus: ");
scanf("%d", &age); // loeb täisarvu
printf("Sisestatud vanus on: %d\n", age);
return 0;
}
Tähelepanekud
- Kui andmeid ei sisestata õiges vormingus, võib tekkida vigu.
- Oluline on piirata sisendi suurust, et vältida puhvermäluga seotud ületäitumisi (nt
%s
kasutamisel).
fgets
funktsiooni kasutamine
fgets
loeb sisendi ridade kaupa ja seda peetakse turvalisemaks kui scanf
.
Põhisüntaks
char *fgets(char *str, int n, FILE *stream);
str
: massiiv, kuhu sisend salvestatakse.n
: maksimaalne loetavate märkide arv (massiivi suurus).stream
: sisendi allikas (tavaliseltstdin
).
Kasutusnäide
#include <stdio.h>
int main() {
char name[50];
printf("Sisesta oma nimi: ");
fgets(name, 50, stdin); // loeb kuni 49 märki
printf("Sisestatud nimi on: %s", name);
return 0;
}
Tähelepanekud
- Kui sisestatud tekst ületab puhversuuruse, siis ülejäänud osa kärbitakse.
- Kui sisendis on reavahetus, tuleb see käsitsi eemaldada.
Kuidas eemaldada reavahetusmärk
name[strcspn(name, "\n")] = '\0';
scanf
ja fgets
võrdlus
Omadus | scanf | fgets |
---|---|---|
Kasutus | Arvude või stringide lugemine kindla vormingu järgi | Tekstirea lugemine tervikuna |
Turvalisus | Võib põhjustada puhvrimälu ületäitumist | Võimaldab kontrollida puhversuurust |
Paindlikkus | Toetab vormingutunnuseid | Loeb kogu sisendi stringina |
Kumb valida?
- Kui kasutada
scanf
: sobib, kui on vaja otse lugeda numbreid või kindlat tüüpi andmeid. - Kui kasutada
fgets
: sobib, kui tähtis on turvalisus ja sisend võib olla pikk või keeruline.
4. Turvaline standardse sisendi kasutamine
Standardse sisendi töötlemisel C-keeles on turvalisuse tagamine äärmiselt oluline. Valesti teostatud sisend võib põhjustada puhvrimälu ületäitumisi või määratlemata käitumist ning vähendada programmi töökindlust. Selles jaotises käsitleme, kuidas standardset sisendit turvaliselt rakendada, koos praktiliste näidetega.
Kuidas vältida puhvrimälu ületäitumist
scanf
on mugav, kuid ilma sisendi suurust piiramata võib tekkida puhvrimälu ületäitumine. Selle vältimiseks tuleb määrata maksimaalne sisendisuurus vormingutunnuses.
Näide sisendi piiramise kohta
#include <stdio.h>
int main() {
char input[10];
printf("Sisesta string (kuni 9 märki): ");
scanf("%9s", input); // loeb kuni 9 märki
printf("Sisestatud string: %s\n", input);
return 0;
}
Olulised punktid
- Kasutades nt
%9s
, saab piirata sisendi pikkust ja vältida massiivi ületamist.
Turvaliseks sisendiks kasuta fgets
fgets
võimaldab määrata loetavate märkide arvu, vähendades sellega puhvrimälu ületäitumise riski. See sobib eriti hästi pikkade stringide või terve rea lugemiseks.
fgets
kasutamise näide
#include <stdio.h>
#include <string.h>
int main() {
char buffer[20];
printf("Sisesta string: ");
fgets(buffer, sizeof(buffer), stdin); // loeb kuni 19 märki
buffer[strcspn(buffer, "\n")] = '\0'; // eemaldab reavahetuse
printf("Sisestatud string: %s\n", buffer);
return 0;
}
Olulised punktid
sizeof(buffer)
abil saab puhversuuruse määrata automaatselt.strcspn
funktsiooni abil eemaldatakse sisendist reavahetusmärk.
Sisendandmete kontrollimine
Et tagada turvaline sisendi töötlemine, tuleb kasutaja sisestatud andmeid alati kontrollida. Näiteks kui eeldatakse täisarvu sisestamist, tasub sisend esmalt lugeda stringina ning seejärel teha teisendus ja vigade kontroll.
Näide täisarvu kontrollimise kohta
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
char buffer[20];
long number;
char *endptr;
printf("Sisesta täisarv: ");
fgets(buffer, sizeof(buffer), stdin);
errno = 0; // lähtesta veaseisund
number = strtol(buffer, &endptr, 10); // teisenda string täisarvuks
if (errno != 0 || endptr == buffer || *endptr != '\0') {
printf("Palun sisesta kehtiv täisarv.\n");
} else {
printf("Sisestatud täisarv: %ld\n", number);
}
return 0;
}
Olulised punktid
strtol
võimaldab avastada teisenduse käigus tekkivaid vigu.errno
jaendptr
koos annavad teada, kas teisendustulemus oli korrektne.
Vigade käsitlemise parimad tavad
Standardse sisendi töötlemisel on korrektne veakontroll võtmetähtsusega töökindluse tagamiseks.
Näide veakontrollist
#include <stdio.h>
int main() {
int value;
printf("Sisesta täisarv: ");
if (scanf("%d", &value) != 1) { // kui sisend ebaõnnestub
printf("Sisend on vigane.\n");
return 1; // lõpetab veaga
}
printf("Sisestatud täisarv: %d\n", value);
return 0;
}
Olulised punktid
- Tuleb kontrollida
scanf
tagastusväärtust ja teha veakäsitlus, kui sisend ei vasta oodatud vormingule.
Turvalise sisenditöötluse kokkuvõte
scanf
kasutamisel tuleb alati piirata sisendi suurust vormingutunnusega.- Pikemate stringide või rea kaupa sisendi jaoks kasuta
fgets
. - Ära usalda pimesi kasutaja sisendit – tee alati kontroll ja veakäsitlus.
5. Standardse sisendi rakenduslik kasutamine
Kui oled õppinud standardse sisendi põhitõed, tasub edasi liikuda keerukamate kasutusjuhtude juurde. See võimaldab töödelda mitmekesisemaid sisendandmeid ja olukordi. Selles jaotises käsitleme näiteks mitme väärtuse korraga sisestamist ning reavahetuste ja tühikute käsitlemist.
Mitme andme sisestamine korraga
Sageli tuleb töödelda mitut väärtust, mis sisestatakse standardse sisendi kaudu. Allpool on toodud näited, kuidas lugeda andmeid, mis on eraldatud tühikute või komadega.
Näide tühikuga eraldatud sisendist
#include <stdio.h>
int main() {
int numbers[5];
printf("Sisesta 5 täisarvu, eraldades need tühikutega: ");
for (int i = 0; i < 5; i++) {
scanf("%d", &numbers[i]); // loeb tühikuga eraldatud arvud
}
printf("Sisestatud arvud: ");
for (int i = 0; i < 5; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
Näide komaga eraldatud sisendist
#include <stdio.h>
int main() {
int numbers[3];
printf("Sisesta 3 täisarvu, eraldades need komadega: ");
scanf("%d,%d,%d", &numbers[0], &numbers[1], &numbers[2]); // loeb komaga eraldatud arvud
printf("Sisestatud arvud: %d, %d, %d\n", numbers[0], numbers[1], numbers[2]);
return 0;
}
Sisendi käsitlemine, mis sisaldab reavahetusi ja tühikuid
Standardse sisendi korral võib sisendis olla nii reavahetusi kui ka tühikuid. Järgnevalt vaatame, kuidas neid õigesti töödelda.
Näide reavahetuse käsitlemisest
Kui sisendis on reavahetus, saab seda töödelda kasutades fgets
funktsiooni ning eemaldades reavahetuse käsitsi.
#include <stdio.h>
#include <string.h>
int main() {
char input[100];
printf("Sisesta tekstirida: ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = '\0'; // eemaldab reavahetuse
printf("Sisestatud tekst: %s\n", input);
return 0;
}
Mitmerealise sisendi töötlemine
Mõnikord on vaja lugeda mitut rida järjest ja töödelda neid ükshaaval. Seda kasutatakse näiteks tekstianalüüsis ja andmetöötluses.
Näide mitmerealisest sisendist
#include <stdio.h>
int main() {
char line[100];
printf("Sisesta mitu tekstirida (lõpetamiseks vajuta Ctrl+D):\n");
while (fgets(line, sizeof(line), stdin) != NULL) {
printf("Sisestatud rida: %s", line);
}
return 0;
}
Dünaamilise sisendi töötlemine
Kui sisendandmete arv ei ole ette teada, tuleb neid töödelda dünaamiliselt. Järgmises näites sisestatakse tundmatu arv täisarve ja arvutatakse nende summa.
Näide dünaamilise sisendi töötlemisest
#include <stdio.h>
int main() {
int number, sum = 0;
printf("Sisesta täisarve (lõpetamiseks vajuta Ctrl+D):\n");
while (scanf("%d", &number) == 1) {
sum += number;
}
printf("Sisestatud arvude summa: %d\n", sum);
return 0;
}
Kokkuvõte
Rakenduslike sisenditöötluse tehnikate abil saab luua programme, mis töötlevad keerulisemaid andmeid ja kohanduvad dünaamiliste olukordadega. Kui harjuda mitme andme korraga lugemise ja reavahetuste käsitlemisega, on võimalik luua veelgi arenenumaid programmilahendusi.
6. Levinumad probleemid ja nende lahendused
C-keeles standardse sisendi kasutamisel puutuvad algajad sageli kokku erinevate probleemidega. Allpool on toodud levinumad olukorrad ja nende lahendused, mis aitavad luua töökindlamaid programme.
scanf
probleemid ja lahendused
Probleem 1: Sisendi vahelejätmine
scanf
kasutamisel võivad reavahetused või tühikud mõjutada järgmist sisendilugemist.
Näide
#include <stdio.h>
int main() {
int number;
char letter;
printf("Sisesta täisarv: ");
scanf("%d", &number);
printf("Sisesta märk: ");
scanf("%c", &letter); // loeb kogemata reavahetuse
printf("Sisestatud arv: %d, märk: %c\n", number, letter);
return 0;
}
Lahendus
Et vältida reavahetuse lugemist, lisa enne %c
vormingutühiku.
scanf(" %c", &letter); // tühik ignoreerib eelnevad reavahetused
Probleem 2: Puhvrimälu ületäitumine
Kui scanf
abil loetakse liiga pikk string, võib see puhvrimälu ületada ja põhjustada programmi kokkujooksmise.
Näide
char input[10];
scanf("%s", input); // kui sisend on pikem kui 9 märki, tekib ületäitumine
Lahendus
Piira sisendi pikkust vormingutunnusega.
scanf("%9s", input); // piirab sisendi 9 märgiga
Või kasuta turvalisemat alternatiivi – fgets
.
fgets
probleemid ja lahendused
Probleem 1: Reavahetuse käsitlemine
fgets
lisab sisestuse lõppu reavahetuse märgi, mis võib põhjustada ootamatut käitumist stringivõrdluse või andmete töötlemise ajal.
Näide
char input[20];
fgets(input, sizeof(input), stdin);
if (strcmp(input, "yes") == 0) {
printf("Sisend on 'yes'.\n");
}
Sellisel juhul loetakse stringiks "yes\n"
ning võrdlus ebaõnnestub.
Lahendus
Eemalda reavahetuse märk.
input[strcspn(input, "\n")] = '\0';
Sisendvigade käsitlemine
Probleem 1: Vigane sisend
Kui oodatakse täisarvu, aga sisestatakse hoopis string, võib programm töötada valesti.
Näide
int number;
scanf("%d", &number); // kui sisestatakse tekst, võib programm käituda valesti
Lahendus
Kontrolli alati sisendi kehtivust.
if (scanf("%d", &number) != 1) {
printf("Vigane sisend.\n");
while (getchar() != '\n'); // puhasta sisendipuhver
}
Mitmerealise sisendi probleemid
Probleem: scanf
ja fgets
segakasutus
Kui programmis kasutatakse nii scanf
kui ka fgets
, võib tekkida ootamatu käitumine.
Põhjus
scanf
jätab reavahetuse sisendipuhvrisse, mistõttu järgmine fgets
loeb selle kohe ära.
Lahendus
Puhasta sisendipuhver pärast scanf
kasutamist.
while (getchar() != '\n');
Kokkuvõte
C-keeles standardse sisendi kasutamisel on mitmeid ohukohti, kuid kui mõista probleemide põhjuseid ja neid õigesti lahendada, on võimalik kirjutada turvalisi ja tõhusaid programme. Eriti oluline on mõista scanf
ja fgets
erinevusi ning valida vastavalt vajadusele sobiv meetod.

7. Näited standardse sisendi kasutamisest
Siin toome praktilised näited, kuidas standardset sisendit kasutada erinevates olukordades – alates lihtsatest juhtumitest kuni veidi keerukamate lahendusteni.
Näide 1: Arvude summa ja keskmise leidmine
Programm võtab mitu täisarvu standardse sisendi kaudu ning arvutab nende summa ja keskmise.
#include <stdio.h>
int main() {
int numbers[100];
int count = 0, sum = 0;
float average;
printf("Sisesta täisarve, eralda need tühikutega (lõpetamiseks vajuta Ctrl+D):\n");
while (scanf("%d", &numbers[count]) == 1) {
sum += numbers[count];
count++;
}
if (count > 0) {
average = (float)sum / count;
printf("Summa: %d, Keskmine: %.2f\n", sum, average);
} else {
printf("Ühtegi arvu ei sisestatud.\n");
}
return 0;
}
Näide 2: Palindroomi kontroll
Programm kontrollib, kas sisestatud string on palindroom (loe sama nii eest- kui tagantpoolt).
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool isPalindrome(char str[]) {
int start = 0;
int end = strlen(str) - 1;
while (start < end) {
if (str[start] != str[end]) {
return false;
}
start++;
end--;
}
return true;
}
int main() {
char input[100];
printf("Sisesta string: ");
fgets(input, sizeof(input), stdin);
// eemalda reavahetus
input[strcspn(input, "\n")] = '\0';
if (isPalindrome(input)) {
printf("Sisestatud string on palindroom.\n");
} else {
printf("Sisestatud string ei ole palindroom.\n");
}
return 0;
}
Näide 3: CSV-andmete töötlemine
Programm loeb komaga eraldatud väärtusi ja töötleb neid ükshaaval.
#include <stdio.h>
#include <string.h>
int main() {
char input[200];
char *token;
printf("Sisesta andmed CSV-formaadis: ");
fgets(input, sizeof(input), stdin);
// eemalda reavahetus
input[strcspn(input, "\n")] = '\0';
// eralda komadega
token = strtok(input, ",");
while (token != NULL) {
printf("Väärtus: %s\n", token);
token = strtok(NULL, ",");
}
return 0;
}
Näide 4: Interaktiivne programm dünaamilise sisendiga
Programm võtab kasutajalt korduvalt sisendit ja käitub vastavalt sisestatud käsule.
#include <stdio.h>
#include <string.h>
int main() {
char input[50];
printf("Sisesta 'exit', et programm lõpetada.\n");
while (1) {
printf("Sisesta käsk: ");
fgets(input, sizeof(input), stdin);
// eemalda reavahetus
input[strcspn(input, "\n")] = '\0';
if (strcmp(input, "exit") == 0) {
printf("Programm lõpetati.\n");
break;
} else {
printf("Sisestatud käsk: %s\n", input);
}
}
return 0;
}
Kokkuvõte
Rakenduslikud näited standardse sisendi kasutamisest aitavad mõista, kuidas luua interaktiivseid ja praktilisi programme. Kasuta neid näiteid inspiratsiooniks ning kohanda neid vastavalt oma projektide vajadustele.
8. Kokkuvõte
Selles artiklis selgitasime standardse sisendi kasutamist C-keeles alates põhitõdedest kuni rakenduslike näideteni. Loodetavasti mõistad nüüd paremini, kuidas standardne sisend töötab, kuidas seda turvaliselt kasutada ja kuidas seda praktikas rakendada.
Standardse sisendi olulisuse kordamine
- Standardne sisend on põhiline viis, kuidas programm saab andmeid väljastpoolt ja töötab dünaamiliselt.
- C-keeles saab kasutada
scanf
jafgets
funktsioone numbrite ja stringide lugemiseks.
Turvalise ja tõhusa sisendi töötlemise põhipunktid
- Väldi puhvrimälu ületäitumist
- Kasuta
scanf
puhul sisendi pikkuse piiranguid (nt%9s
). - Pikemate stringide või ridade lugemiseks kasuta
fgets
.
- Sisendi valideerimine
- Numbrilise sisendi korral kasuta
strtol
võistrtod
ning kontrolli vigu. - Vigase sisendi korral rakenda korrektset veakäsitlust.
- Rakenduslikud tehnikad
- Mitme andme korraga lugemisel ja reavahetuste töötlemisel kasuta õigeid meetodeid.
Järgmised sammud
Kui oled omandanud standardse sisendi põhitõed, saad oma oskusi täiendada järgmiste sammudega:
- Standardne väljund ja veaväljund: õpi, kuidas väljastada veateateid ja logisid.
- Failide töötlemine: kombineeri failisisend standardse sisendiga, et luua keerukamaid programme.
- Praktilised ülesanded: loo ise väikseid projekte, võttes eeskujuks artiklis toodud näiteid.
Sõnum lugejale
Standardne sisend on C-keele programmeerimise üks alustalasid, kuid samas ka sügav teema. Selle artikli abil loodetavasti mõistad, kuidas sisendit turvaliselt ja tõhusalt töödelda. Õpi samm-sammult, lahenda väikeseid küsimusi ja liigu järk-järgult edasi – see on kindel tee programmeerimisoskuste arendamiseks.