← Kursa Dön
📄 Text · 15 min

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.78

Her << 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): false

Dikkat: 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:

  1. Yeni satır karakteri (\n) ekler.

  2. Çı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
PerformansDaha yavaşDaha hızlı
Ne zaman kullanDebug, 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: \n kullan, 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: 30

cin >> 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:

  1. Baştaki boşlukları (whitespace) atlar.

  2. Tipe uygun karakterleri okur.

  3. 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çin getline() 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: 25

Ne 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: 25

std::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ı getline kullanacaksan mutlaka cin.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        18500

Varsayı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       25

setprecision 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 TL

setfill — 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örHeaderAçıklamaKalıcı mı?
std::endl<iostream>Yeni satır + flushHayır
std::setw(n)<iomanip>Alan genişliğiHayır (tek kullanımlık)
std::setprecision(n)<iomanip>Basamak sayısıEvet
std::fixed<iostream>Sabit ondalık gösterimEvet
std::scientific<iostream>Bilimsel gösterimEvet
std::left<iostream>Sola hizalamaEvet
std::right<iostream>Sağa hizalamaEvet
std::setfill(c)<iomanip>Dolgu karakteriEvet
std::boolalpha<iostream>bool'u true/false yazEvet
std::showbase<iostream>Taban prefix'i gösterEvet
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::format ile 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; endl sadece buffer flush gerektiğinde kullan.

  • cin >> sonrası getline kullanacaksan `cin.ignore()` ile tamponu temizle — aksi halde getline boş satır okur.

  • `<iomanip>` header'ındaki setw, setprecision, fixed, setfill ile 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.