sscanf nedir?sscanf, Y_Less adlı kullanıcı tarafından yapılan dizelerden veri çıkarma işlevini sağlayan bir eklentidir. Klasik tanımlamayı geçecek olursak esasında print nasıl çıktı fonksiyonu ise sscanf eklentisinide girdi fonksiyonu olarak tanımlayabiliriz. Klavyeden girdiğiniz değeri formatlayıp bize çıktı verecektir. Örneğin 2 ve r tuşlarına bastığınızda bunların ne olduğunu size yeniden söyleyecektir. Üzgünüm ki şu söylediğimi anlayabilmek için biraz bilgili olmanız gerekiyor. Klasik bilinen işlevlerinin aksine ileri seviye sayılabilecek (klasik scriptlerde gördüğümüz kullanımlarının dışında) birçok işlevide vardır ve bu konunun amacı klasik bir anlatımdan (mysql kayıt sistemi yapımı gibi mysql eklentisinin ne olduğundan bahsetmeden direk "balığı vermeceli". ki bunu eleştirmiyorum, yanlış anlaşılmasın.) ziyade komple her şeyiyle anlatmaktır, en azından bunu denemektir. Eksiklerim, yanlışlarım olabilir çünkü ben bir insanım. Ricâm saçma yorumlarla konu altında ego kasma olaylarının olmaması zira bir şeyleri yanlış aktardıysam bunları güzel bir şekilde düzeltmeniz güzel fakat anlaşılmayı etkilemeyen basit bir şey üzerinden "bu budur" gibi kalıplarla egonuzu tatmin etmeyiniz. Bu konuyu açıyor olma amacım ilgili insanlara bir şekilde faydalı olabilmek, foruma katkıda bulunmak. Bunu unutmadan devam edelim.
new sayi1, sayi2;
sscanf("17 310", "ii", sayi1, sayi2);
Burada "ii" kısmı "tam sayı tam sayı" anlamına geliyor, öncesindeki parametreye bakacak olursak "17 ve 310" sayılarını görüyoruz. Bu veriler tam sayı olduğu için "i" belirtecini kullandık.
new sayi1, sayi2;
if(sscanf("17 merhaba", "ii", sayi1, sayi2))
{
printf("Girilen verilerin ikisi de tam sayı değildi.");
}
Burada merhaba bir tam sayı olmadığı için bize böyle bir dönüş yaptı.
Nasıl Kullanabilirim?sscanf eklentisini kullanmak istiyorsanız öncelikle bunu pawn satırlarında belirtmeniz gerekiyor.
#include <sscanf2>
Ardından server.cfg belgesine eklemeniz gerekiyor.
plugins sscanf
Bir örnekle nasıl göründüğünü açıklamak gerekirse sscanf şöyle görünür:
if(sscanf(params, "ui", oyuncuid, miktar))
{
return SendClientMessage(playerid, -1, "Kullanım: /paraver <oyuncu id/ismi> <miktar>");
}
Giriş kısmında i'den bahsetmiştik. i tek belirtecimiz değil, bunun gibi birçok belirteç var. Bunları aşağıdaki görselden görebilirsiniz.
(https://i.hizliresim.com/dsfv85y.png)
StringsMetin dizeleri için kullanılan bir belirteçtir. Fazla bahsedecek bir şey yok kısaca:
sscanf("merhaba 27", "si", str, val);
verecektir:
Alıntı yapılan: undefinedhello 27
Burada anlatılacak şeylerin sayısı çok fakat bunları kısaca özetlemek gerekirse string verileri için s tagını kullandığımız ve bunun toplama özelliğine sahip olması. Zaten bunu yukarıdaki örnekte de görebiliyoruz. Eğer
sscanf("merhaba dünya", "s ", str);
şeklinde yapsaydık, bu bize
Alıntı yapılan: undefinedmerhaba
çıktısını verecekti. Çünkü s kullandıktan sonra boşluk bıraktık. Fakat
sscanf("merhaba dünya", "s", str);
şeklinde kullansaydık
Alıntı yapılan: undefinedmerhaba dünya
çıktısını alırdık.
Burada şu anlık anlatmaya değer başka bir şey bulmuyorum fakat başka kullanımlar, detaylarda mevcut bunları da öğreneceğim ben illaki diyenler olabilir diye en alta konunun yabancı anlatımını da koyacağım.
Paketlenmiş StringlerPaketlenmiş metin dizeleri için kullanılan bir belirteçtir. Normal string anlatımından farkı şudur:
sscanf(params, "s[32]I(15)", isim, numara);
Burada string değeri için 32 hücre belirledik, konumuz bu değil. Konumuz burada I ile gösterdiğimiz belirteçin yanında parantez içinde belirttiğimiz 15 opsiyonsuz bir şekilde 15 olması. Yani integer değerinin ne olduğunu direkt olarak belirtmiş (umarım anlatabilmişimdir, soru işareti kaldıysa yardımcı olabilirim) oluyoruz.
ArraylerBilmeyenler için array aynı tipten çok sayıda değişken tanımlamak için kullanılır ve burada array nedir bunu daha uzunca anlatamam üzgünüm.
new arr[5];
sscanf("1 2 3 4", "a<i>[5]", arr);
Bu bize dört adet veri verecektir. Veri diyorum çünkü bunu command ekranına yazdırdığımızda sonuç olarak "1 2 3 4" almayacağız, semboller alacağız. Ne demek istediğimi anlamadıysanız ilk giriş kısmını yeniden okuyunuz.
A<s[6]>(selam)[4]
Bu ise bize varsayılan olarak şunları üretecektir:
Alıntı yapılan: undefined"selam", "selam", "selam", "selam"
Bakın dikkat ederseniz burada üretecektir diyorum çünkü burada alacağımız çıktıyı en başta giriyoruz. Burada dikkat etmemiz gereken ikinci konu ise a belirtecini bu kez büyük harfle yapıyor olmamızdı. Paketlenmiş stringlerde kısmında nasıl büyük harf kullandığımızda çıktıyı sscanf fonksiyonu içerisinde belirtiyorsak burada da harf büyüyünce aynı sonucu almış olduk diyebiliriz.
EnumlarYine enum içinde veri çıktısı alabiliyoruz. Yukarda dediklerimi toparlayıp burada ne yaptığını anlayabiliriz. Örneğe geçecek olursak:
enum E_VERI
{
veri_a,
Float: veri_f,
veri_s[32],
veri_z
}
main
{
new var[E_VERI];
sscanf("1 12.0 Can c", "e<ifs[32]c>", var);
}
Burada verdiğim örnekte:
- e, enumdan okumaya başlar.
- i, 1'e yani veri_a'ya karşılık gelmektedir.
- f, 12.0'a yani veri_f'e karşılık gelmektedir.
- s, Can'a yani veri_s'e karşılık gelmektedir.
- c, c'ye yani veri_z'ye karşılık gelmektedir.
SınırlayıcılarBiliyorum, bunları Türkçeye çevirmek oldukça komik fakat mecburum. Sınırlayıcıları sizlere bir örnek üzerinde anlatayım. Örneğin hatalı e-posta adresi girişini saptamak ve engellemek istiyorsunuz. Bu amaçla yola çıkarak bunu nasıl engelleyebileceğimize dair bir düşünceye girelim. E-posta adresi rumuz@mail.com gibi kalıplardır. Biz bu kontrolde diyeceğiz ki önce bir string (elliotalderson7) girilmeli sonra @ işareti koyulmalı sonra başka bir string (gmail, outlook) girilmeli ve nokta koyulmalı, en son başka bir string (com, net) daha girilmelidir. İşte bunu p belirtecini kullanarak yapabiliriz.
sscanf(eposta, "p<@>s[32]s[32]", str, str);
Bu sonuç olarak girilen e-posta adresinin iki stringinin arasına @ işareti koyacaktır. Bu bölümü örnekle gayet net şekilde anlattığımı düşünüyorum.
Özel Belirteçlersscanf'ın son sürümü kendi özel belirtecimizi (k) yapmamız için imkan veriyor.
SSCANF:oyuncudurumu(string[])
{
if ('0' <= string <= '9')
{
new ret = strval(string);
if (0 <= ret <= 9)
{
return ret;
}
}
else if (!strcmp(string, "PLAYER_STATE_NONE")) return 0;
else if (!strcmp(string, "PLAYER_STATE_ONFOOT")) return 1;
else if (!strcmp(string, "PLAYER_STATE_DRIVER")) return 2;
else if (!strcmp(string, "PLAYER_STATE_PASSENGER")) return 3;
else if (!strcmp(string, "PLAYER_STATE_WASTED")) return 7;
else if (!strcmp(string, "PLAYER_STATE_SPAWNED")) return 8;
else if (!strcmp(string, "PLAYER_STATE_SPECTATING")) return 9;
}
sscanf(params, "uk<oyuncudurumu>", playerid, state);
Anlatım yabancı (asıl yazarının) kaynağında burada bitmiyor fakat benim anlatımım burada bitiyor, ilgi olursa devamını da anlatırım. Bunun dışında bahsedeceğim çokta bir şey yok aslında.
KaynakBu eklenti Y_Less tarafından kodlanmış olup Emmet_ tarafından uzun süre devam ettirilmiştir ve şu an yeniden Y_Less tarafından geliştirilmeye devam etmektedir. Aşağıdaki bağlantıları kullanarak asıl anlatıma ve indirebilirsiniz.
- https://github.com/Y-Less/sscanf
- https://www.burgershot.gg/showthread.php?tid=426
Başarılı bir konu anlatımı olmuş, yeni başlayanlar bu rehberden yararlanabilir. Emeğine sağlık :helal: