25 Nisan 2016 Pazartesi

-Java ile Android ve JSP ile Web Programlama Eğitim Setleri-

Merhaba,
Dijibil.com  üzerinden iki adet eğitim setim yayınlandı.

-"Java İle Android Programlama Eğitim Seti" Süre: 50 saat 35 dk.
 
-"JSP ile Web Programlama Eğitim Seti"   Süre: 27 saat 46 dk.


-Özel Tasarım Toast Kullanımı(Android)-

Merhabalar,
Android ile ilgili karşılaştığım  bir soruda "resimli toast" penceresini nasıl oluşturabileceği sorulmuştu.
İlgili soruya istinaden bu makaleyi hazırladım.

Android uygulama geliştirirken arayüz görüntüleme dosyalarını(layout) birçok yerde kullanabiliriz. 
Dolayısıyla kullanıcı ile etkileşimde olan tüm görsel kısım aslında bir layout'dan ibarettir.
Ancak geliştiriciler,belli işlem sonuçlarını kullanıcıya göstermek istediklerinde çoğunlukla standart görsellik araçlar ve apilere başvururlar.
Bunlardan birisi de dialog pencereleridir. Dialog pencereleri standart halde görüntülenebildiği gibi,özel tasarımlara sahip pencereler de oluşturulabilir.
Dolayısıyla tamamen kendi tasarımımızı layout olarak oluşturup görüntüleyebiliriz.
Bu içerikte "Toast" mesaj penceresi konu alınmıştır ve tüm içeriğe aşağıda yer verilmiştir.
Öncelikle mesaj penceresinin görsel kısmını oluşturan bir layout.xml dosyası oluşturmalıyız.

toast_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/toast_layout_id" 
              android:orientation="horizontal" 
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent" 
              android:padding="10dp" 
              android:background="#DAAA" 
              > 
    <ImageView android:id="@+id/image1" 
               android:layout_width="wrap_content" 
               android:layout_height="fill_parent" 
               android:layout_marginRight="10dp" 
               /> 
    <TextView android:id="@+id/text1" 
              android:layout_width="wrap_content" 
              android:layout_height="fill_parent" 
              android:textColor="#FFF" 
              /> 
</LinearLayout>

Java kısmı:

 //layout dosyası çağırabilmemiz için gereken referans tanımı:
 LayoutInflater inflater = getLayoutInflater(); 

 //referans üzerinden oluşturduğumuz layout.xml dosyasına erişiyoruz ve LinearLayout kontrolüne ait id ismini çekiyoruz:
 View layoutToast = inflater.inflate(R.layout.toast_layout,(ViewGroup) findViewById(R.id.toast_layout_id)); 

 //mesaj penceresi üzerinde bir resim dosyası yer alacağı için ilgili kontröle erişiyoruz:
 ImageView image = (ImageView) layoutToast.findViewById(R.id.image1); 
 image.setImageResource(R.drawable.ic_launcher); 

 //mesaj penceresi üzerinde bir TextView kontrolü yer alacağı için ilgili kontrole erişiyoruz:
 TextView text = (TextView) layoutToast.findViewById(R.id.text1);

 //toast penceresi görüntüleme kısmı(mesaj içeriği ve tasarımımıza ait layout kısmını ekliyourz):
 text.setText("Merhaba,Resimli Mesaj Penceresi..."); 
 Toast toast = new Toast(getApplicationContext()); 
 toast.setGravity(Gravity.CENTER_HORIZONTAL, 0, 0); 
 toast.setDuration(Toast.LENGTH_LONG); 
 toast.setView(layoutToast); 
 toast.show();

Uygulama görüntüsü:


23 Nisan 2016 Cumartesi

-Kendimize ait Listener(dinleyici) Oluşturma-

Merhabalar,
NOT: makale içeriğinde geçen sözcükler ve karşılıkları:
-Listener = "dinleyici"
-Kontoller = "JButton,JTextField,JFrame vb."
-Component = "genel-özel amaçlı kontroller"

Bazı durumlarda mevcut kontroller tam olarak ihtiyacımıza cevap vermeyebilir.
Bu gibi durumlarda kendimize ait kontroller-componentler geliştirmemiz gerekebilir.
İhtiyacımıza yönelik bir kontrol geliştirmek için farklı yol ve yönteme başvurulabilir.
Bazı durumlarda mevcut kontrolleri revize ederek,ihtiyacımıza yönelik özellikler ekleyerek çözüm getirilir.
Bu yazı,kendimize ait Listener oluşturma hakkında olacaktır.
Java'da kullanılan herhangi bir kontrolü revize ederek,veya kendimiz geliştirdiğimiz componente Listener oluşturabiliriz.
Bu durumda revize edilmiş ilgili kontroller bizim Listener ile çalışacaktır.
Aşağıda verilen örnek uygulamada "JTextField" kontrolü için özel bir Listener geliştirilmiştir.
Geliştirdiğimiz Listener "keyPress,keyReleased ve mouseListener" işlevlerine sahiptir.
Daha fazla özellik eklemek için "JComponent" sınıfı dökümantasyonundan yararlanabilirsiniz.
Uygulamamız Main.java ve TextFieldComponent.java class'lara sahiptir.

TextFieldComponent.java içeriği:

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JComponent;

public class TextFieldComponent extends JComponent {
public TextFieldComponent(){
//constructor

}
   KeyListener keyPressListener = new KeyAdapter() {
       public void keyPressed(KeyEvent keyEvent) {
           int key_code = keyEvent.getKeyCode();
           String which_key = KeyEvent.getKeyText(key_code);
           System.out.println("KeyPress-Key:" + which_key);
       }
     };//keyPressListener
     
     KeyListener keyReleasedListener = new KeyAdapter() {
     @Override
    public void keyReleased(KeyEvent keyEvent) {
     int key_code = keyEvent.getKeyCode();
     String which_key = keyEvent.getKeyText(key_code);
     System.out.println("KeyReleased-Key:" + which_key);
    }
     };//keyReleasedListener
     
     MouseListener mouseListener = new MouseAdapter() {
       public void mousePressed(MouseEvent mouseEvent) {
        int x = mouseEvent.getX();
        int y = mouseEvent.getY();
        int xx = mouseEvent.getXOnScreen();
        int yy = mouseEvent.getYOnScreen();
        int cc = mouseEvent.getClickCount();
        System.out.println("x:" + x);
        System.out.println("y:" + y);
        System.out.println("xx:" + xx);
        System.out.println("yy:" + yy);
        System.out.println("cc:" + cc);
       
         int mgetButton = mouseEvent.getButton();
         switch(mgetButton){
         case 0x1:
         System.out.println("BUTTON LEFT");
         break;
         case 0x2:
         System.out.println("BUTTON CENTER(wheel)");
             break;
         default:
           System.out.println("BUTTON RIGHT");
             break;
         }//switch
         }
     };//mouseListener
}

Main.java içeriği:
import javax.swing.JFrame;
import javax.swing.JTextField;

public class Main {
public static void main(String[] args) {
TextFieldComponent myTextFieldComponent = new TextFieldComponent();
   JFrame jFrame = new JFrame();
   jFrame.setBounds(550, 250, 300, 300); //pencere ölçüleri ve ekrandaki yerleşme planı.
   jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   JTextField textField = new JTextField();
   textField.addKeyListener(myTextFieldComponent.keyPressListener);
   textField.addKeyListener(myTextFieldComponent.keyReleasedListener);
   textField.addMouseListener(myTextFieldComponent.mouseListener);
   textField.requestFocus();
   jFrame.add(textField, "North");
   jFrame.setVisible(true);//pencereyi görünür yap.

}

}

Uygulama görüntüsü:

20 Nisan 2016 Çarşamba

-CC++ Fonksiyonların Pointer İle Çağrılması-

Merhabalar,
C/Cpp programlama dilinde pointer(işaretci) önemli bir yere sahiptir.
Aslında C'yi farklı kılan özelliklerden biri de pointer kavramı olduğu aşikar.
Bu durumda pointer kavramı oldukça geniş çerçevede kullanılır.Ancak bu makalede fonksiyonların pointer ile kullanımını göreceğiz.
Dolayısıyla fonksiyonun pointer ile çağrılması ve fonksiyonun başka bir fonksiyona parametre verilmesi işlenecektir.
Aşağıda,fonksiyonu gösteren bir pointer tanımına yer verilmiştir:

tip (*fonksiyon_adi)(arguman_tipleri)

Bu durumda genel tanım şu şekilde açıklanabilir:
tip                     = Gösterilecek fonksiyonun geri dönüş değerini temsil eder. Yani fonksiyon 'int' döndürüyorsa bu değer 'int' olarak tanımlanmalıdır.
fonksiyon_adi   = Asıl fonksiyonu gösterecek değişken adı/ismi olarak tanımlanır. Ancak gösterilecek fonksiyon ile aynı isimde olması gerekmez.
     Yani değişken ismi gibi esnek tanımlanabilir.(fonksiyon_adi başında '*'(pointer) işareti olduğuna dikkat ediniz.)
   
arguman_tipleri = Gösterilecek fonksiyonun aldığı parametre sayısı kadar parametre tipleri belirlenmelidir.
                  Yani gösterilecek 'fonksiyon(char c,int a)' şeklinde ise 'arguman_tipleri' '(char,int)' şeklinde olmalıdır.

Örnek 1:

//standart int türünde parametre alan fonksiyon tanımı:
void fonksiyon1(int x)
{
    printf( "%d\n", x );
}

int main()
{   
    //fonksiyonu gösteren pointer oluşturuluyor:
    void (*fonk)(int);
 
    /*tanımlanan pointer'e fonksiyon1 atanıyor.Bu noktadan sonra 'fonk' artık 'fonksiyon1''i temsil edecektir.
      Ancak istenildiği taktirde "fonkisyon1(deger)" şeklinde de kullanılabilir. Yani pointer gösterilen fonksiyon kendi ismiyle de çağrılabilir.
    */
    fonk = fonksiyon1;
    
    //fonksiyon1'e parametre gönderiliyor:
    fonk(44);
    
    //fonksiyon normal çağrılıyor:
    fonksiyon1(100);
    
    return 0;
}   
 
Ayrıca pointer'e fonksiyon adresi atanarak kullanılabilir.
Örnek:
fonk = &fonksiyon1;


Örnek 2:
float topla(int a,int b)
{
 return a + b;
}
float bol(int a,int b)
{
 return a / b;
}

float carp(int a,int b)
{
return a * b;
}

float cikar(int a,int b)
{
return a - b;
}


int main()
{
int a = 20;
int b = 2;

  float (*fonk)(int,int); 
fonk = topla;
printf("%d,%d'nin toplami:%f\n",a,b,fonk(a,b));

fonk = bol;
printf("%d,%d'nin bolumu: %f\n",a,b,fonk(a,b));

fonk = carp;
printf("%d,%d'nin carpimi: %f\n",a,b,fonk(a,b));

fonk = cikar;
printf("%d,%d'nin cikarma: %f\n",a,b,fonk(a,b));
}
Yukarıda verilen örneğin "main" kısmını incelediğimizde bir kez tanımlanmış gösterici ile 
tüm fonksiyonlar çağrılmıştır-erişilmiştir.
Dolayısıyla aynı dönüş değeri ve arguman tiplerine sahip birden fazla fonksiyonu tek pointer tanımı vasıtasıyla çağırmak-erişmek mümkündür.
Aksi durumda yeni pointer oluşturmak gereklidir.

Son örneğimiz ise oluşturulan pointer'in başka bir fonksiyona parametre geçmek ile alakalıdır.
Örnek:

 //fonksiyon parametre gönderilecek fonksiyon işaretçisi 'typedef' olarak tanımlanmalıdır.
 typedef float (*fonksiyon)(int a, int b);

float topla(int a,int b)
{
 return a + b;
}
float bol(int a,int b)
{
 return a / b;
}

float carp(int a,int b)
{
return a * b;
}

float cikar(int a,int b)
{
return a - b;
}

 //tüm işlemlere aracılık yapacak fonksiyonumuz.Aynı zamanda 3. parametresi fonksiyon pointer parametre alır.
float islemler(int a,int b, fonksiyon fonk)
{
float sonuc = fonk(a,b);
    return sonuc;
}
int main()
{
int a = 20;
int b = 2;

printf("%d,%d'nin toplami:%f\n",a,b,islemler(a,b,topla));
 
printf("%d,%d'nin bolumu: %f\n",a,b,islemler(a,b,bol));

printf("%d,%d'nin carpimi: %f\n",a,b,islemler(a,b,carp));

printf("%d,%d'nin cikarma: %f\n",a,b,islemler(a,b,cikar));
 
return 0;
}
Çıktı:
20,2'nin toplami:22.000000
20,2'nin bolumu: 10.000000
20,2'nin carpimi: 40.000000
20,2'nin cikarma: 18.000000

İyi çalışmalar.

16 Nisan 2016 Cumartesi

-Gelişmiş Enum Kullanımı-

Merhaba,
Enum konusunda bana yöneltilen bir soru neticesinde bu makaleyi yazma gereği duydum.

Bu makale Java ile Enum(Enumaration) kullanımı hakkında olacaktır.
Programlama dillerinde Enum kullanımı yaygındır. Enum,belirli değerleri sabit olarak tanımlamak için kullanılır.
Sabit olarak tanımlayacağımız değerler her türden olabilir. Yani bu noktada "object" kavramı devreye girecektir.
Dolayısıyla enum içersinde veri türleri,yapılandırıcılar(constructor) ve fonksiyonlar tanımlayabiliriz.
Böylece farklı yapılarda ve amaçla geliştirdiğimiz sınıfları(class) da enum içerisinde kullanabiliriz.
Aşağıda standart bir enum kullanımına yer verilmiştir.

public enum Standart {
    ZERO,
    ONE,
    TWO,
    UNKNOWN
}
public static void main(String[] args) {
           System.out.println(Standart.ZERO);
           System.out.println(Standart.ONE);
}
Çıktı:
ZERO
ONE

Yukarıda verilen örnek standart bir kullanımı ifade eder. En temel "enum" kullanımında öğretilen-öğrenilen örnektir.
Ancak enum kavramı tıpkı bir "class" kavramı gibi esnektir. Dolayısıyla class yapısında kullanabildiğimiz tüm esnekliği "enum" ile sergilemek mümkündür.
Aşağıda verilen örneği inceleyelim:

public enum WebSite {
    /*
    Enum içersinde tanımlanmış sabit değerlerin parametre aldığını görüyoruz.
    İlk baktığımızda standart bir yapılandırıcı(constructor) kullanımına benzetebiliriz. 
    Ancak haksız sayılmayız. Çünkü enum içeriği tıpkı bir sınıf(class) gibi tasarlanmıştır.
    Dolayısıyla "sabit" olarak belirlenmiş değerler aslında bir yapılandırıcı(constructor) modelini sergiler.
    Bu durumda "GOOGLE" sabitine atanan "google" ve "www.google.com.tr" içeriği "WebSite" constructor'a gider.
    Yani "GOOGLE" sabiti aslında 'WebSite("google","www.google.com.tr")' kullanımına eşdeğerdir.
    Aynı şekilde diğer sabitler(FACEBOOK,DIJIBIL,...) aynı kullanımı ifade eder.
    */
    GOOGLE("google","www.google.com.tr"),
    FACEBOOK("facebook","www.facebook.com"),
    DIJIBIL("dijibil","www.dijibil.com"),
    KERIMFIRAT("kerimfirat","www.kerimfirat.blogspot.com");
  
    
    String name;
    String url;
    WebSite(String _name,String _url) {
        this.name = _name;
        this.url = _url;
    }

     public String getName() {
        return name;
    }
    public String getUrl(){
        return url;
    }

/*
     * Standart Enum kullanımında değerler sabittir. Ancak bu şekilde genişletilmiş bir yapı,enum değerlerini
      değiştirmemizi mümkün kılar.
      Aşağıdaki fonksiyon bu iş için tasarlanmıştır.
     */
    public void setName(String _name,String _url)
    {
        this.name = _name;
        this.url = _url;
        
    }
   
}
    
    public static void main(String[] args) {
          System.out.println(WebSite.GOOGLE.getName()+ "," +WebSite.GOOGLE.getUrl());
          System.out.println(WebSite.FACEBOOK.getName()+ "," +WebSite.FACEBOOK.getUrl());
          System.out.println(WebSite.DIJIBIL.getName()+ "," +WebSite.DIJIBIL.getUrl());
          System.out.println(WebSite.KERIMFIRAT.getName()+ "," +WebSite.KERIMFIRAT.getUrl());
        
WebSite.GOOGLE.setName("GOOG", "google.com");
         System.out.println(WebSite.GOOGLE.getName()+ "," +WebSite.GOOGLE.getUrl());
    }
Çıktı:
google,www.google.com.tr
facebook,www.facebook.com
dijibil,www.dijibil.com
kerimfirat,www.kerimfirat.blogspot.com
GOOG,google.com

Yukarıda verilen örnekte görüldüğü gibi 'enum' içeriğini genişletebiliriz.
Böylece enum ile birlikte fonksiyon kullanabilir ve enum sabit tanımlamalar üzerinde farklı işlemler gerçekleştirebilir.
Aşağıda verilen örnekte enum içeriği dizi olarak alınmıştır:
   public static void main(String[] args) {
        for (WebSite content : WebSite.values()) {
            System.out.println(content);
        }
  //farklı işlem:
           System.out.println( WebSite.valueOf("GOOGLE"));
    }
Çıktı:
GOOGLE
FACEBOOK
DIJIBIL
KERIMFIRAT
GOOGLE
İyi çalışmalar.

13 Nisan 2016 Çarşamba

-Cache Risk-volatile--

Merhaba,
Bu makalemde,özellikle hardware programlama düzeyinde sıklıkla kullandığımız veya kullanmak zorunda olduğumuz 'volatile' anahtar sözcüğüne değineceğim.
Özellikle 'hardware' olarak belirtmemdeki sebep,bu alanda yaşadığım bir deneyim neticesinde konuya bağlı kalmak için belirtiyorum.
Ancak geliştirmekte olduğunuz kod,amacına uygun olarak belli kullanım gereksinimleri doğurur. Dolayısıyla 'hardware' olarak sınırlanamaz.

-volatile nedir ve neden kullanmalıyız?
Bu anahtar kelimeyi tanıtmadan evvel,derleyici bazında kod optimizasyon konusunda biraz bilgi sahibi olmamız gerekir. Bu noktada kullandığımız derleyici ve derleyiciden istediğimiz işlevler önem teşkil etmektedir.
Daha açık olarak: Gelişmiş derleyiciler geliştirici isteği dışında kodların işleyiş mantığına müdahalede bulunur. Buradaki amaç,gereksiz kod boyutundan ve çalışma zamanından feragat etmektir.
Örneğin tanımladığımız bir değişkeni hiçbir yerde kullanmıyorsak bunun uygulama boyutuna gereksiz etkisi vardır. Veya uygulama çalışma esnasında sıkça başvurulan bir alan(değişken,fonksiyon vb) çalışma zamanına olumsuz etki edebilir. Bu noktada derleyici optimizasyon özelliği devreye girer.
Sık sık başvurulan alanların değerleri,daha hızlı erişim amaçlı çeşitli şekillerde saklanarak optimizasyon sağlanılır.
Optimizasyona gerek duyulan örnek:
int c = 0;
for(int i =0; i<100;i++)
{
 c = i;
}
Bu kod parçasında 'c' değişkeni tanımlanmış fakat herhangi bir yerde kullanılmamıştır.
Veya aşağıdaki kod parçası önrek verilebilir:
if(false){
 printf(".....");
}
Bu kullanımda hiçbir zaman if içerisine girilmeyecektir. Bu durumda uygulama boyutu düşünülerek
optimizasyon uygulanır.
Ancak derleyici tarafından sağlanan optimizasyon özelliğini kullanmak geliştirici insiyatifine verilmiştir. Dolayısıyla geliştirici bu özelliği kullanmak istediğini/istemediğini belirtebilir.

Derleyici optimizasyon özelliğini kullanmak yarar sağlayacağı için önerilir. Fakat optimizasyon durumları bazı istenmeyen sonuçları meydana getirebilir. Bu sonuçlardan biri de sıklıkla başvurulan/çağrılan(değer yazılıp,değer okunan) alanlardır. Bu şekilde kullanımda olan alanlara hızlıca erişim sağlanabilmesi için(çalışma zamanı) değeri genelde cache kısmında saklanır.
Ancak bu işleyiş çok işlemcili cihazlarda istenmeyen durumlar meydana getirebilir.
Örneğin böyle bir alanın işleyişini aynı anda birden fazla işlemci erişmesi(işleme alması) durumunda,
biri nihayi değer yazarken diğeri bu değeri değiştirebilir. Yani birden fazla thread'in aynı anda erişmesi bu durumu yaşatabilir. Böyle bir durumda işlemin sonucu dolayısıyla ilgili alanın değeri değişecektir. Örneğin SD kart okuma esnasında ilgili donanımın hazır olup olmadığını belirleyen kritik değer alanı böyle bir tehdit altında olmamalıdır. Veya bir donanım REG(register) değeri için de aynı durum sözkonusudur. Sonuç itibariyle böyle bir durumun yaşanmaması için ihtimal bırakmamalıyız.Bunun için  başvurulacak anahtar kelime 'volatile''dir.

'volatile' olarak tanımlanmış bir alan,derleyici optimizasyon işleminden emin olmak içindir.
Yani derleyici 'volatile' olarak tanımlanmış bir alana optimizasyon işlemi uygulamaz.
Ayrıca,'volatile' tanımlanmış bir alanın değeri "cache" yerine  main(ana) memory'e yazılır ve okunur.
Bu alanın değeri 'cache'a yazılıp okunmadığı için yukarıda anlatılan istenmeyen sonuçlara karşı bir miktar garantiye alınmıştır. Ancak bu tanımlama tek başına yeterli değildir.
Örneğin birden fazla Thread 'volatile' bir değişkenin değerini main memory'dan aynı anda işleme alırsa risk meydana gelir.
Bu durumdan tamamen emin olmak için "mutex" ile "lock/unlock"(Cpp için) ile garantiye almalıyız.
Örnek:
#include<mutex>
std::mutex _mutex;
volatile int i;
volatile int REG;
 _mutex.lock();//kilitle
for(i =0 ; i<32; i++)
{
 REG = i << 10;
 REG = ..
 REG = ..
}
_mutex.unlock();//kilidi kaldır.
//...

NOT: Bu yazıda Cpp kullanım örneği verilmiştir. Diğer teknolojiler için eşdeğer yöntemler kullanmalısınız.
Örneğin Java için aşağıdaki örnekler verilebilir:

1:
volatile int count = 0;
 public synchronized void increment() {
        count++;
  }
  
2:
  Lock lock = new Lock();
  volatile int count = 0;

  public int inc(){
    lock.lock();
    count++;
    lock.unlock();
    return count;
  }

Bu makaleyi hazırlamamın nedeni,embedded linux alanındaki çalışmalarımda karşılaştığım bir "main memory" problemi ve buna getirdiğim çözümü size aktarmaktır.
Kitaplarda ve eğitimlerde "volatile" ve "lock" konuları anlatılır. Ancak genellikle "eşzamanlı main memory erişimi nadir olabilecek(düşük/çok düşük ihtimal) bir durumdur"  şeklinde(yaklaşık olarak) açıklar. Risk ihtimali milyarda bir olsa da buna önlem alınmalıdır.
--------------

11 Nisan 2016 Pazartesi

-Linux Kernel C kütüphane Funksiyonları 1-

Merhaba,
Bu makalemde linux kernel içersinde bulunan C kütüphane fonksiyonları işlenmiştir.
Bu fonksiyonların bir bölümünü standart C kütüphanesi içersinde kullanabiliyoruz.
Ancak sadece kernel'e yönelik fonksiyonlar da mevcuttur. 
NOT: Makalenin devamı seriler halinde gelecektir.

>sprintf = Stringi formatlar ve buffer içine yerleştirir.
int sprintf (char *buf, const char *fmt, ...);

Funksiyon argumanları:
-buf = buffer içine sonucu yerleştirmek için.
-fmt = formatlanacak string belirlenir.
-... = String formatı için argumanlar belirlenir.

Dönüş değeri:
Bu fonksiyon 'buf' içine yazılan karakter sayısını döndürür.

NOT: Tampon taşmalarını önlemek için bunun yerine 'snprintf' veya 'scnprintf' kullanılması önerilir.
Örnek kullanım:
char buf[20] = "kerim fırat nasılsın";
int a =  sprintf(buf,"kerimfiratppppppppppppppppppppppppp");
printf("boyut:%d\n",a);
printf("%s\n",buf);

Çıktı:(tampon taşma sağlandı)
boyut:35
kerimfiratppppppppppppppppppppppppp
*** stack smashing detected ***: ./test2 terminated
Aborted (core dumped)


>snprintf = Stringi formatlar ve buffer içine yerleştirir.
int snprintf (char *buf, size_t size, const char *fmt, ...);
Funksiyon argumanları:
-buf  = buffer içine sonucu yerleştirmek için.
-size = tampon boyutu,sondaki boş alan da dahil.
-fmt  = formatlanacak string belirlenir.
-... = String formatı için argumanlar belirlenir.

Dönüş değeri:
fmt olarak belirlenen stringin karakter sayısını döndürür,sondaki boş alan hariçtir.
Bu funksiyonun özelliği 'size' olarak tampon boyutunun belirlenebilmesidir.Format stringi tampon boyutunu aşması durumunda veri içeriği üzerinde kesintiye gidilir.

Örnek kullanım:
char buf[20] = "kerim fırat nasılsın";
int a =  snprintf(buf, 11, "kerimfiratppppppppppppppppppppppppp");
printf("boyut:%d\n",a);
printf("%s\n",buf);
Çıktı:
boyut:35
kerimfirat


>scnprintf = Stringi formatlar ve buffer içine yerleştirir.
int scnprintf (char *buf, size_t size, const char *fmt, ...);
Funksiyon argumanları:
-buf  =  buffer içine sonucu yerleştirmek için.
-size = tampon boyutu,sondaki boş alan da dahil.
-fmt  = formatlanacak string belirlenir.
-... = String formatı için argumanlar belirlenir.

Dönüş değeri:
fmt olarak belirlenen stringin karakter sayısını döndürür,sondaki '\0' karakter dahil değildir.
Eğer 'size' boyutu 0'a eşitse,funksiyonun dönüş değeri 0 olur.


>vsprintf = Stringi formatlar ve buffer içine yerleştirir.
int vsprintf (char *buf, const char *fmt, va_list args);
Funksiyon argumanları:
-buf  = buffer içine sonucu yerleştirmek için.
-fmt  = formatlanacak string belirlenir.
-args = formatlanacak string için argumanlar belirlenir.

Dönüş değeri:
'buf' içersine yazılan karakter sayısını döndürür.

Örnek kullanım:
Yapacağımız örnekte iki ayrı veri tek veri haline getirilecektir.
'vsprintf' funksiyonu parametre olarak 'args' aldığı için birden fazla veri gönderilebilir.
Bu örnekte iki veri gönderiliyor.

char buf[80];
int vspfunc(char *fmt, ...)
{
   va_list aptr;
   int ret;
   va_start(aptr, fmt);
   ret = vsprintf(buf, fmt, aptr);
   va_end(aptr);

   return ret;
}

int main()
{
   int i = 44;
   char str[50] = "kerimfirat.blogspot.com";
   int r = vspfunc("%d %s",i,str);
   printf("%s\n", buf);
}
Çıktı:
44 kerimfirat.blogspot.com



---