cin/cout ile Giriş-Çıkış İşlemleri
Bir programın kullanıcıyla iletişim kurmasının iki temel yolu var: çıktı vermek (ekrana yazmak) ve girdi almak (klavyeden okumak). C++'ta bu işleri cout ve cin nesneleri yapar.
Bu derste giriş-çıkış (I/O) işlemlerini derinlemesine öğreneceğiz. Sadece ekrana "Merhaba" yazmayacağız — formatlama, hata yönetimi ve pratik kullanım tekniklerini de göreceğiz.
cout ile Ekrana Yazma
cout (character output) standart çıktı akışıdır (standard output stream). Veriyi ekrana yazdırmak için kullanılır.
Temel Kullanım
#include <iostream>
int main() {
std::cout << "Merhaba, Dunya!";
return 0;
}<< sembolüne ekleme operatörü (insertion operator) denir. Sağındaki veriyi cout akışına "ekler" — yani ekrana gönderir.
🚰 Analoji:
cout'u bir su borusu gibi düşün.<<operatörü o boruya veri akıtır. Ne akıtırsan akıt — metin, sayı, karakter — hepsi borudan geçip ekrana ulaşır.
Zincirleme Yazdırma
<< operatörünü zincirleme kullanarak birden fazla veriyi tek satırda yazdırabilirsin:
#include <iostream>
int main() {
std::string isim = "Ali";
int yas = 25;
double boy = 1.78;
std::cout << "Ad: " << isim << ", Yas: " << yas << ", Boy: " << boy << std::endl;
return 0;
}Ad: Ali, Yas: 25, Boy: 1.78Her << yeni bir veri ekler. Farklı tipleri (string, int, double) sorunsuz karıştırabilirsin — cout tipi otomatik tanır.
Farklı Veri Tiplerini Yazdırma
#include <iostream>
int main() {
// Tam sayilar
std::cout << "int: " << 42 << std::endl;
// Ondalikli sayilar
std::cout << "double: " << 3.14159 << std::endl;
// Karakterler
std::cout << "char: " << 'A' << std::endl;
// Boolean
std::cout << "bool (true): " << true << std::endl; // 1 yazdırır
std::cout << "bool (false): " << false << std::endl; // 0 yazdırır
// Boolean'ı metin olarak yazdırma
std::cout << std::boolalpha;
std::cout << "bool (true): " << true << std::endl; // true yazdırır
std::cout << "bool (false): " << false << std::endl; // false yazdırır
return 0;
}int: 42
double: 3.14159
char: A
bool (true): 1
bool (false): 0
bool (true): true
bool (false): falseDikkat: bool değerler varsayılan olarak 1 ve 0 olarak yazdırılır. std::boolalpha ile true / false metnine dönüştürebilirsin.
endl vs \n — Satır Sonu
İki yöntem de yeni satıra geçirir ama aralarında önemli bir fark var.
std::endl
std::cout << "Birinci satir" << std::endl;
std::cout << "Ikinci satir" << std::endl;endl iki iş yapar:
Yeni satır karakteri (
\n) ekler.Çıktı tamponunu (output buffer) temizler (flush).
\n
std::cout << "Birinci satir\n";
std::cout << "Ikinci satir\n";\n sadece yeni satır karakteri ekler. Tampon temizlemez.
Hangisini Kullanmalı?
endl | \n | |
|---|---|---|
| Yeni satır | ✅ | ✅ |
| Buffer flush | ✅ | ❌ |
| Performans | Daha yavaş | Daha hızlı |
| Ne zaman kullan | Debug, kritik çıktı | Genel kullanım |
Çoğu durumda \n yeterli ve daha performanslı. endl'i her satırda kullanmak, özellikle döngülerde, programı yavaşlatabilir:
// YAVAS — her iterasyonda buffer flush
for (int i = 0; i < 10000; ++i) {
std::cout << i << std::endl;
}
// HIZLI — buffer otomatik yönetilir
for (int i = 0; i < 10000; ++i) {
std::cout << i << '\n';
}💡 İpucu: Genel kural:
\nkullan,endl'i sadece çıktının hemen görünmesi gereken durumlarda (debug, loglama) kullan.
cin ile Klavyeden Okuma
cin (character input) standart girdi akışıdır (standard input stream). Kullanıcının klavyeden girdiği veriyi okur.
Temel Kullanım
#include <iostream>
int main() {
int yas;
std::cout << "Yasinizi girin: ";
std::cin >> yas;
std::cout << "Yasiniz: " << yas << '\n';
return 0;
}Yasinizi girin: 25
Yasiniz: 25>> sembolüne çıkarma operatörü (extraction operator) denir. cin akışından veri "çıkarır" ve değişkene atar.
Birden Fazla Girdi Okuma
#include <iostream>
#include <string>
int main() {
std::string isim;
int yas;
double boy;
std::cout << "Adiniz: ";
std::cin >> isim;
std::cout << "Yasiniz: ";
std::cin >> yas;
std::cout << "Boyunuz (metre): ";
std::cin >> boy;
std::cout << '\n' << "--- Bilgileriniz ---" << '\n';
std::cout << "Ad: " << isim << '\n';
std::cout << "Yas: " << yas << '\n';
std::cout << "Boy: " << boy << " m" << '\n';
return 0;
}Ya da tek satırda birden fazla değişken okuyabilirsin:
int x, y;
std::cout << "Iki sayi girin (boslukla ayirin): ";
std::cin >> x >> y;
std::cout << "Toplam: " << x + y << '\n';Iki sayi girin (boslukla ayirin): 10 20
Toplam: 30cin >> x >> y ifadesi önce x'i, sonra y'yi okur. Değerler boşluk, tab veya Enter ile ayrılır.
cin'in Davranışı
cin >> operatörü şöyle çalışır:
Baştaki boşlukları (whitespace) atlar.
Tipe uygun karakterleri okur.
Bir boşluk veya uyumsuz karakter gördüğünde durur.
Bu davranış önemli. cin >> isim yazdığında ve kullanıcı "Ali Veli" girerse, sadece "Ali" okunur. "Veli" tampon bellekte (buffer) kalır.
std::string isim;
std::cin >> isim;
// Kullanıcı "Ali Veli" yazarsa:
// isim = "Ali" (boşlukta durur)
// "Veli" tamponda bekler⚠️ Dikkat:
cin >>boşluk içeren metinleri okuyamaz. Tam bir satır okumak içingetline()kullanmalısın.
getline() ile String Okuma
Boşluk içeren metinleri okumak için std::getline() kullanılır:
#include <iostream>
#include <string>
int main() {
std::string tam_isim;
std::cout << "Tam adinizi girin: ";
std::getline(std::cin, tam_isim);
std::cout << "Merhaba, " << tam_isim << "!\n";
return 0;
}Tam adinizi girin: Ali Veli Yilmaz
Merhaba, Ali Veli Yilmaz!getline satır sonuna (\n) kadar tüm karakterleri okur — boşluklar dahil.
cin >> ve getline Karışımı — Tehlikeli Bölge
cin >> ve getline'ı arka arkaya kullandığında bir tuzak var:
#include <iostream>
#include <string>
int main() {
int yas;
std::string isim;
std::cout << "Yasiniz: ";
std::cin >> yas; // 25 Enter
std::cout << "Adiniz: ";
std::getline(std::cin, isim); // Bu satır atlanır!
std::cout << "Ad: " << isim << ", Yas: " << yas << '\n';
return 0;
}Yasiniz: 25
Adiniz: Ad: , Yas: 25Ne oldu? cin >> yas sayıyı okudu ama Enter tuşunun oluşturduğu \n karakteri tamponda kaldı. getline bu \n'i gördü ve boş string okudu.
Çözüm: Tamponu Temizle
#include <iostream>
#include <string>
int main() {
int yas;
std::string isim;
std::cout << "Yasiniz: ";
std::cin >> yas;
std::cin.ignore(); // Tampondaki \n'i at
std::cout << "Adiniz: ";
std::getline(std::cin, isim);
std::cout << "Ad: " << isim << ", Yas: " << yas << '\n';
return 0;
}Yasiniz: 25
Adiniz: Ali Veli
Ad: Ali Veli, Yas: 25std::cin.ignore() tampondaki bir sonraki karakteri (genellikle \n) atar. Daha güvenli versiyon:
#include <limits>
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');Bu satır, tampondaki \n'e kadar tüm karakterleri atar. cin >> ile getline karıştırıyorsan her zaman bu kalıbı kullan.
⚠️ Dikkat:
cin >>sonrasıgetlinekullanacaksan mutlakacin.ignore()çağır. Bu, yeni başlayanların en çok yaşadığı sorunlardan biridir.
Girdi Doğrulama
Kullanıcı her zaman beklediğin tipte girdi girmez. Sayı beklerken metin girerse ne olur?
#include <iostream>
int main() {
int sayi;
std::cout << "Bir sayi girin: ";
std::cin >> sayi;
if (std::cin.fail()) {
std::cout << "Gecersiz girdi!\n";
std::cin.clear(); // Hata bayrağını temizle
std::cin.ignore(10000, '\n'); // Tamponu temizle
} else {
std::cout << "Girdiginiz sayi: " << sayi << '\n';
}
return 0;
}Bir sayi girin: abc
Gecersiz girdi!Döngüyle Doğrulama
Geçerli bir girdi alana kadar sormaya devam et:
#include <iostream>
#include <limits>
int main() {
int yas;
while (true) {
std::cout << "Yasinizi girin (1-120): ";
std::cin >> yas;
if (std::cin.fail()) {
std::cout << "Lutfen bir sayi girin!\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
if (yas >= 1 && yas <= 120) {
break; // Gecerli girdi — donguden cik
}
std::cout << "Yas 1-120 arasinda olmali!\n";
}
std::cout << "Yasiniz: " << yas << '\n';
return 0;
}Bu kalıp (pattern) gerçek programlarda çok kullanılır. Kullanıcı girdisine asla güvenme — her zaman doğrula.
Çıktı Formatlama
Sayıları düzgün biçimde yazdırmak için <iomanip> header'ındaki formatlama araçlarını kullanırız.
setw — Alan Genişliği
setw(n) bir sonraki çıktının minimum n karakter genişliğinde yazdırılmasını sağlar:
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::setw(10) << "Ad" << std::setw(10) << "Yas" << std::setw(15) << "Maas" << '\n';
std::cout << std::setw(10) << "Ali" << std::setw(10) << 25 << std::setw(15) << 15000.50 << '\n';
std::cout << std::setw(10) << "Ayse" << std::setw(10) << 30 << std::setw(15) << 22000.75 << '\n';
std::cout << std::setw(10) << "Mehmet" << std::setw(10) << 28 << std::setw(15) << 18500.00 << '\n';
return 0;
} Ad Yas Maas
Ali 25 15000.5
Ayse 30 22000.8
Mehmet 28 18500Varsayılan olarak sağa hizalanır. Sola hizalamak için std::left kullan:
std::cout << std::left;
std::cout << std::setw(10) << "Ali" << std::setw(10) << 25 << '\n';
// Ali 25setprecision ve fixed — Ondalık Basamak
#include <iostream>
#include <iomanip>
int main() {
double pi = 3.14159265358979;
// Varsayilan: 6 anlamli basamak
std::cout << "Varsayilan: " << pi << '\n';
// setprecision: toplam anlamli basamak sayisi
std::cout << "precision 3: " << std::setprecision(3) << pi << '\n';
std::cout << "precision 8: " << std::setprecision(8) << pi << '\n';
// fixed + setprecision: ondalik basamak sayisi
std::cout << std::fixed;
std::cout << "fixed 2: " << std::setprecision(2) << pi << '\n';
std::cout << "fixed 4: " << std::setprecision(4) << pi << '\n';
std::cout << "fixed 10: " << std::setprecision(10) << pi << '\n';
return 0;
}Varsayilan: 3.14159
precision 3: 3.14
precision 8: 3.1415927
fixed 2: 3.14
fixed 4: 3.1416
fixed 10: 3.1415926536`setprecision(n)` tek başına: toplam anlamlı basamak sayısı.
`fixed` + `setprecision(n)`: ondalık noktadan sonraki basamak sayısı.
Para birimi yazdırırken fixed + setprecision(2) kullanışlıdır:
double fiyat = 49.9;
std::cout << std::fixed << std::setprecision(2);
std::cout << "Fiyat: " << fiyat << " TL\n";
// Fiyat: 49.90 TLsetfill — Dolgu Karakteri
setw ile oluşan boşlukları farklı bir karakterle doldurabilirsin:
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::setfill('0') << std::setw(5) << 42 << '\n'; // 00042
std::cout << std::setfill('.') << std::setw(20) << "Merhaba" << '\n'; // .............Merhaba
std::cout << std::setfill('-') << std::setw(30) << "" << '\n'; // ------------------------------
return 0;
}Sayı Tabanları
#include <iostream>
int main() {
int sayi = 255;
std::cout << "Onluk (decimal): " << std::dec << sayi << '\n'; // 255
std::cout << "Sekizlik (octal): " << std::oct << sayi << '\n'; // 377
std::cout << "Onaltilik (hex): " << std::hex << sayi << '\n'; // ff
// Prefix ile
std::cout << std::showbase;
std::cout << "Onluk: " << std::dec << sayi << '\n'; // 255
std::cout << "Sekizlik: " << std::oct << sayi << '\n'; // 0377
std::cout << "Onaltilik:" << std::hex << sayi << '\n'; // 0xff
return 0;
}Pratik Örnek: Fatura Yazdırma
Öğrendiklerimizi birleştirelim:
#include <iostream>
#include <iomanip>
#include <string>
int main() {
// Urunler
std::string urun1 = "Laptop";
std::string urun2 = "Mouse";
std::string urun3 = "Klavye";
double fiyat1 = 15999.99;
double fiyat2 = 249.90;
double fiyat3 = 599.50;
int adet1 = 1, adet2 = 2, adet3 = 1;
double toplam = fiyat1 * adet1 + fiyat2 * adet2 + fiyat3 * adet3;
double kdv = toplam * 0.20;
double genel_toplam = toplam + kdv;
// Formatlama
std::cout << std::fixed << std::setprecision(2);
// Baslik
std::cout << std::string(50, '=') << '\n';
std::cout << std::setw(35) << "FATURA" << '\n';
std::cout << std::string(50, '=') << '\n';
// Tablo basligi
std::cout << std::left
<< std::setw(15) << "Urun"
<< std::setw(10) << "Adet"
<< std::setw(12) << "Birim"
<< std::setw(12) << "Toplam" << '\n';
std::cout << std::string(50, '-') << '\n';
// Urunler
std::cout << std::setw(15) << urun1
<< std::setw(10) << adet1
<< std::setw(12) << fiyat1
<< std::setw(12) << fiyat1 * adet1 << '\n';
std::cout << std::setw(15) << urun2
<< std::setw(10) << adet2
<< std::setw(12) << fiyat2
<< std::setw(12) << fiyat2 * adet2 << '\n';
std::cout << std::setw(15) << urun3
<< std::setw(10) << adet3
<< std::setw(12) << fiyat3
<< std::setw(12) << fiyat3 * adet3 << '\n';
// Alt toplam
std::cout << std::string(50, '-') << '\n';
std::cout << std::setw(37) << "Ara Toplam:" << std::setw(12) << toplam << '\n';
std::cout << std::setw(37) << "KDV (%20):" << std::setw(12) << kdv << '\n';
std::cout << std::string(50, '=') << '\n';
std::cout << std::setw(37) << "GENEL TOPLAM:" << std::setw(12) << genel_toplam << '\n';
std::cout << std::string(50, '=') << '\n';
return 0;
}Bu program düzgün hizalanmış bir fatura çıktısı üretir. setw, left, fixed, setprecision — hepsini kullandık.
Formatlama Manipülatörleri Özet Tablosu
| Manipülatör | Header | Açıklama | Kalıcı mı? |
|---|---|---|---|
std::endl | <iostream> | Yeni satır + flush | Hayır |
std::setw(n) | <iomanip> | Alan genişliği | Hayır (tek kullanımlık) |
std::setprecision(n) | <iomanip> | Basamak sayısı | Evet |
std::fixed | <iostream> | Sabit ondalık gösterim | Evet |
std::scientific | <iostream> | Bilimsel gösterim | Evet |
std::left | <iostream> | Sola hizalama | Evet |
std::right | <iostream> | Sağa hizalama | Evet |
std::setfill(c) | <iomanip> | Dolgu karakteri | Evet |
std::boolalpha | <iostream> | bool'u true/false yaz | Evet |
std::showbase | <iostream> | Taban prefix'i göster | Evet |
std::dec/oct/hex | <iostream> | Sayı tabanı | Evet |
Önemli: setw tek kullanımlık — her çıktıdan önce tekrar yazmalısın. Diğer manipülatörler bir kez ayarlandığında değiştirilene kadar geçerli kalır.
💡 İpucu: C++20'de
std::formatile daha modern formatlama yapılabilir:std::format("Pi = {:.2f}", 3.14159)— Python'un f-string'ine benzer. Derleyicin destekliyorsa tercih et.
Özet
`std::cout <<` ekrana yazdırır;
<<operatörünü zincirleme kullanarak farklı tipleri tek satırda yazdırabilirsin.`std::cin >>` klavyeden okur; boşlukta durur, bu yüzden boşluklu metin okumak için `std::getline()` kullanılır.
`\n` performans için
endl'den daha iyi bir tercih;endlsadece buffer flush gerektiğinde kullan.cin >>sonrasıgetlinekullanacaksan `cin.ignore()` ile tamponu temizle — aksi haldegetlineboş satır okur.`<iomanip>` header'ındaki
setw,setprecision,fixed,setfillile profesyonel çıktı formatlama yapabilirsin.Kullanıcı girdisine asla güvenme — `cin.fail()` ile girdi doğrulaması yap, geçersiz girdide tamponu temizle ve tekrar sor.
AI Asistan
Sorularını yanıtlamaya hazır