Kirish / chiqish: scanf va printf
Dastur foydalanuvchi bilan qanday gaplashadi?
Hozircha biz faqat ekranga ma'lumot chiqardik. Lekin haqiqiy dastur ikki tomonlama ishlaydi:
Foydalanuvchi → [klaviatura] → dastur → [ekran] → foydalanuvchi
Bu ikki yo'nalish:
- Chiqish (output):
printf— dasturdan ekranga - Kirish (input):
scanf— klaviaturadan dasturga
Ikkalasi ham stdio.h da — Standard Input/Output.
Kirish va chiqish qanday ishlaydi?
C da ma'lumot oqim (stream) orqali o'tadi. Uch ta standart oqim mavjud:
| Oqim | Yo'nalish | Manba |
|---|---|---|
stdin |
kirish | klaviatura |
stdout |
chiqish | ekran |
stderr |
xato chiqish | ekran |
scanf → stdin dan o'qiydi
printf → stdout ga yozadi
printf — chuqurroq
Sintaksis
printf("format satr", argument1, argument2, ...);
Format specifierlar
| Specifier | Tur | Misol |
|---|---|---|
%d |
int (o'nlik) |
25 |
%u |
unsigned int |
4000000 |
%f |
float / double |
3.140000 |
%e |
Ilmiy yozuv | 3.140000e+00 |
%g |
Qisqaroq f yoki e | 3.14 |
%c |
char |
A |
%s |
Satr (string) | Salom |
%p |
Pointer (manzil) | 0x7fff... |
%x |
O'n oltilik | 1a |
%ld |
long int |
1000000000 |
%lf |
double (scanf da) |
3.14 |
%% |
% belgisi |
% |
Kenglik va aniqlik
#include <stdio.h>
int main() {
int son = 42;
float kasr = 3.14159f;
char satr[] = "Salom";
// Kenglik (width) — minimum joy
printf("[%d]\n", son); // [42]
printf("[%5d]\n", son); // [ 42] — o'ngga tekis
printf("[%-5d]\n", son); // [42 ] — chapga tekis
printf("[%05d]\n", son); // [00042] — nol bilan to'ldir
// Aniqlik (precision) — kasrdan keyingi raqamlar
printf("[%f]\n", kasr); // [3.141590]
printf("[%.2f]\n", kasr); // [3.14]
printf("[%.4f]\n", kasr); // [3.1416]
printf("[%8.2f]\n", kasr); // [ 3.14]
// Satr kenglik
printf("[%s]\n", satr); // [Salom]
printf("[%10s]\n", satr); // [ Salom]
printf("[%-10s]\n", satr); // [Salom ]
return 0;
}
Natija:
[42]
[ 42]
[42 ]
[00042]
[3.141590]
[3.14]
[3.1416]
[ 3.14]
[Salom]
[ Salom]
[Salom ]
Bir nechta argument
#include <stdio.h>
int main() {
char harf = 'A';
int yosh = 19;
float gpa = 3.75f;
printf("Harf: %c, Yosh: %d, GPA: %.2f\n", harf, yosh, gpa);
return 0;
}
Natija:
Harf: A, Yosh: 19, GPA: 3.75
⚠️ Muhim: Argumentlar tartibi va specifierlar tartibi mos kelishi shart. Mos kelmasa — noto'g'ri natija yoki dastur ishdan chiqadi.
scanf — foydalanuvchidan ma'lumot olish
Sintaksis
scanf("format", &o'zgaruvchi);
& — nima uchun kerak?
& — manzil olish operatori. scanf qiymatni
to'g'ridan-to'g'ri o'zgaruvchiga yozishi kerak.
Buning uchun o'zgaruvchining xotira manzili kerak.
int yosh;
scanf("%d", &yosh); // to'g'ri — manzil bilan
scanf("%d", yosh); // xato — manzilsiz (undefined behavior)
scanf — asosiy ishlatish
int o'qish
#include <stdio.h>
int main() {
int yosh;
printf("Yoshingizni kiriting: ");
scanf("%d", &yosh);
printf("Siz %d yoshdasiz.\n", yosh);
return 0;
}
Ishlash:
Yoshingizni kiriting: 19
Siz 19 yoshdasiz.
float va double o'qish
#include <stdio.h>
int main() {
float narx;
double masofa;
printf("Narxni kiriting: ");
scanf("%f", &narx); // float — %f
printf("Masofani kiriting: ");
scanf("%lf", &masofa); // double — %lf (l harfi bor!)
printf("Narx: %.2f so'm\n", narx);
printf("Masofa: %.3f km\n", masofa);
return 0;
}
⚠️ Diqqat:
scanfdadoubleuchun%lf—lharfi bilan.printfda esa%fikkalasi uchun ham ishlaydi. Bu ko'p chalkashtiradigan joy!
char o'qish
#include <stdio.h>
int main() {
char baho;
printf("Bahongizni kiriting (A/B/C): ");
scanf(" %c", &baho); // bo'sh joy oldida — muhim!
printf("Bahoingiz: %c\n", baho);
return 0;
}
💡
scanf(" %c")—%coldidagi bo'sh joy muhim. U oldingiEnteryoki bo'sh joylarni "yutib" yuboradi. Bo'lmasa — oldingi kiritmadan qolgan\nni o'qib qo'yadi.
Bir vaqtda bir nechta kiritish
#include <stdio.h>
int main() {
int yosh;
float boy;
char jins;
printf("Yosh, bo'y va jins kiriting (masalan: 19 175.5 M): ");
scanf("%d %f %c", &yosh, &boy, &jins);
printf("\n===== Ma'lumotlar =====\n");
printf("Yosh: %d\n", yosh);
printf("Bo'y: %.1f\n", boy);
printf("Jins: %c\n", jins);
return 0;
}
Ishlash:
Yosh, bo'y va jins kiriting (masalan: 19 175.5 M): 19 175.5 M
===== Ma'lumotlar =====
Yosh: 19
Bo'y: 175.5
Jins: M
scanf ning qaytargan qiymati
scanf nechta o'zgaruvchini muvaffaqiyatli o'qiganini
qaytaradi. Bu xatolarni tekshirishda ishlatiladi:
#include <stdio.h>
int main() {
int son;
int natija;
printf("Son kiriting: ");
natija = scanf("%d", &son);
if (natija == 1) {
printf("Qabul qilindi: %d\n", son);
} else {
printf("Xato! Son emas.\n");
}
return 0;
}
To'g'ri kiritilsa:
Son kiriting: 42
Qabul qilindi: 42
Noto'g'ri kiritilsa:
Son kiriting: abc
Xato! Son emas.
Buffer muammosi
scanf ishlatganda bufer (input buffer) tushunchasi
muhim. Bufer — klaviaturadan kiritilgan ma'lumotlar
vaqtincha saqlanadigan joy.
Foydalanuvchi: "25\n" bosdi
Buffer: [ 2 ][ 5 ][\n]
scanf("%d"): 25 ni oldi, \n bufferda qoldi!
Muammo misoli
#include <stdio.h>
int main() {
int yosh;
char baho;
printf("Yosh: ");
scanf("%d", &yosh); // "25\n" — 25 olindi, \n qoldi
printf("Baho: ");
scanf("%c", &baho); // \n ni oldi! — baho kiritilmadi
printf("Yosh: %d, Baho: %c\n", yosh, baho);
return 0;
}
Natija (noto'g'ri):
Yosh: 25
Baho: <- kiritishga imkon bermadi!
Yosh: 25, Baho:
Yechim — bo'sh joy qo'shish
scanf(" %c", &baho); // bo'sh joy \n ni yutadi
Natija (to'g'ri):
Yosh: 25
Baho: A
Yosh: 25, Baho: A
Amaliy dastur — Kalkulyator
#include <stdio.h>
int main() {
double a, b;
char amal;
printf("=== Oddiy Kalkulyator ===\n");
printf("Birinchi son: ");
scanf("%lf", &a);
printf("Amal (+, -, *, /): ");
scanf(" %c", &amal);
printf("Ikkinchi son: ");
scanf("%lf", &b);
printf("\nHisob: %.2f %c %.2f = ", a, amal, b);
if (amal == '+') printf("%.2f\n", a + b);
else if (amal == '-') printf("%.2f\n", a - b);
else if (amal == '*') printf("%.2f\n", a * b);
else if (amal == '/') {
if (b == 0) printf("Xato! Nolga bo'lib bo'lmaydi.\n");
else printf("%.2f\n", a / b);
}
else printf("Noto'g'ri amal!\n");
return 0;
}
Ishlash:
=== Oddiy Kalkulyator ===
Birinchi son: 15.5
Amal (+, -, *, /): *
Ikkinchi son: 4
Hisob: 15.50 * 4.00 = 62.00
Keng tarqalgan xatolar
| Xato | Sabab | Yechim |
|---|---|---|
scanf("%d", yosh) |
& unutilgan |
scanf("%d", &yosh) |
scanf("%d", &narx) — float |
Format mos emas | scanf("%f", &narx) |
scanf("%f", &pi) — double |
l harfi yo'q |
scanf("%lf", &pi) |
scanf("%c") bo'sh joy yutadi |
Buffer tozalanmagan | scanf(" %c", &c) |
Vazifalar
✏️ Vazifa 1 — Salomlashish
Foydalanuvchidan ismining birinchi harfini (
char) va yoshini o'qing. Ekranga:Salom, A! Siz 19 yoshdasiz.formatida chiqaring.
✏️ Vazifa 2 — Aylana hisobi
Foydalanuvchidan radiusni (
double) o'qing. Aylana yuzasi va uzunligini hisoblang:Yuzasi = pi * r * r Uzunlik = 2 * pi * r
double pi = 3.14159265358979ishlating. Natijani%.4fbilan chiqaring.
✏️ Vazifa 3 — Harorat konvertori
Foydalanuvchidan Celsius (
float) o'qing. Fahrenheit va Kelvin ga aylantiring:F = (C * 9/5) + 32 K = C + 273.15Uchta qiymatni chiroyli formatda chiqaring.
✏️ Vazifa 4 — To'rtburchak
Foydalanuvchidan to'rtburchakning eni va bo'yini (
float) o'qing. Yuzasi va perimetrini hisoblang. Natijani%.2fbilan chiqaring.
✏️ Vazifa 5 — Vaqt konvertori
Foydalanuvchidan soniyalar sonini (
int) o'qing. Soat, daqiqa va soniyaga aylantiring:3661 soniya → 1 soat, 1 daqiqa, 1 soniya(
/va%operatorlarini ishlating)
✏️ Vazifa 6 — O'rtacha baho
Foydalanuvchidan 5 ta baho (
float) ni ketma-ket o'qing (5 tascanf). O'rtachasini hisoblang. Natijani%.2fbilan chiqaring.
✏️ Vazifa 7 — Pul almashtirish
Foydalanuvchidan dollar miqdorini (
double) o'qing. So'm va evro ga aylantiring:double dollar_kurs = 12800.0; double evro_kurs = 13500.0;Natijani vergullar bilan chiroyli chiqaring.
✏️ Vazifa 8 — Uchburchak yuzasi
Foydalanuvchidan uchburchak uch tomonini (
floata, b, c) o'qing. Perimetri va Geron formulasi bilan yuzasini hisoblang:s = (a + b + c) / 2 Yuza = sqrt(s * (s-a) * (s-b) * (s-c))
math.hdansqrt()ishlating. Kompilyatsiyada-lmflag qo'shing:gcc vazifa.c -o vazifa -lm
✏️ Vazifa 9 — Printf formatlash
Quyidagi jadval aynan shu ko'rinishda chiqsin (kenglik va tekislash bilan):
Mahsulot Narx Soni -------------------------------- Olma 3500 50 Non 2000 100 Shakar 8000 25
%-15s %7.0f %6dformatini ishlating. Ma'lumotlarni o'zgaruvchilarga joylab chiqaring.
✏️ Vazifa 10 — Kichik bank tizimi
Quyidagi dastur yozing:
Hisob raqamingiz: 1001 Ismingiz (birinchi harf): A Balans (so'm): 500000 === Bank Cheki === Hisob: 1001 Ism: A Balans: 500000.00 so'm Holat: Faol ==================Barcha ma'lumotlar
scanfbilan o'qilsin. Balansdouble, hisob raqamint, ismchar, holat_Bool(1 = Faol).
Xulosa
printf |
scanf |
|
|---|---|---|
| Maqsad | Ekranga chiqarish | Klaviaturadan o'qish |
| Oqim | stdout | stdin |
& kerakmi? |
Yo'q | Ha |
double uchun |
%f |
%lf |
char uchun |
%c |
" %c" (bo'sh joy bilan) |
Qo'shimcha — Advanced (majburiy emas)
Bu bo'lim hozircha o'tkazib yuborishingiz mumkin. Keyinchalik qaytib kelganingizda foydali bo'ladi.
puts va putchar — sodda chiqarish
#include <stdio.h>
int main() {
puts("Salom, Dunyo!"); // printf + \n — avtomatik yangi qator
putchar('A'); // bitta belgi chiqaradi
putchar('\n');
return 0;
}
puts — faqat satr chiqaradi, oxiriga \n o'zi qo'shadi.
putchar — bitta char chiqaradi.
getchar — bitta belgi o'qish
#include <stdio.h>
int main() {
char c;
printf("Belgi kiriting: ");
c = getchar();
printf("Kiritdingiz: %c\n", c);
return 0;
}
scanf(" %c") o'rniga getchar() ishlatish mumkin — ba'zan qulayroq.
fprintf — stderr ga xato chiqarish
#include <stdio.h>
int main() {
int son;
printf("Son kiriting: ");
if (scanf("%d", &son) != 1) {
fprintf(stderr, "Xato: son emas!\n");
return 1;
}
printf("Son: %d\n", son);
return 0;
}
fprintf(stderr, ...) — xato xabarlarini stdout dan
alohida oqimga chiqaradi. Professional dasturlarda
xatolar doim stderr ga yoziladi.
fflush(stdout) — bufer tozalash
printf("Yuklanmoqda...");
fflush(stdout); // ekranga darhol chiqar
// ... uzoq hisob ...
printf(" tayyor!\n");
Ba'zan printf natijasi ekranga darhol chiqmaydi —
buferda to'planadi. fflush uni majburan chiqaradi.
Ayniqsa Windows da va \n bo'lmagan holatlarda kerak.
Keyingi dars
Kiritish va chiqarishni o'rgandik. Endi bu qiymatlar ustida hisob-kitob qilamiz.
6-dars: Arifmetik va mantiqiy operatorlar