Forum: D Programlama Dili RSS
yapı elemanlarına ulaşımda foreach() kullanımı
Sayfa:  1  2  sonraki 
cos00kun #1
Üye Kas 2014 tarihinden beri · 262 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: yapı elemanlarına ulaşımda foreach() kullanımı
Aşağıdaki kodda foreach() kullanarak Saat yapısındaki elemenları ekrana yazdırmanın en basit yolu nedir ? (varsa)  "...." yere ne yazalımki (foreach kullanarak !! ) saat,dakika ve saniye değerlerini ekrana çıkarsın ?
import std.stdio;
struct Saat {
    ushort saat;
    ushort dakika;
    ushort saniye;
}
 
void main()
{
    Saat zaman;    
    foreach(elemanlar;........) {
        write(elemanlar);
    }
    readln();
}
E=mc^2
erdem (Moderatör) #2
Üye Tem 2009 tarihinden beri · 1076 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İlkönce bir tane yapı örneği oluşturmak gerekiyor. Örneğin
    Saat saat = Saat(3, 24, 18);
    writeln(saat.dakika);
Hatta daha iyisi saat yapısının bir toString() işlevi olabilir. Böylece writeln(saat) şeklinde kullanabiliriz.

http://ddili.org/ders/d/yapilar.html
acehreli (Moderatör) #3
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4643 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #1
Bu örnek için döngü şöyle yazılabilir:
    foreach(eleman; __traits(allMembers, Saat)) {
        writeln(__traits(getMember, zaman, eleman));
    }
Her tür yapıyla çalışması için şöyle bir işlev kullanılabilir:
import std.stdio;
struct Saat {
    ushort saat;
    ushort dakika;
    ushort saniye;
}
 
void üyeleriYazdır(T)(auto ref const(T) nesne) {
    foreach(üye; __traits(allMembers, T)) {
        writeln(__traits(getMember, nesne, üye));
    }
}
 
void main()
{
    auto zaman = Saat(1, 2, 3);
    üyeleriYazdır(zaman);
}
Üye isimlerini de içerecek biçimde:
void üyeleriYazdır(T)(auto ref const(T) nesne) {
    foreach(i, üye; __traits(allMembers, T)) {
        if (i != 0) {
            write(", ");
        }
        write(üye, ":", __traits(getMember, nesne, üye));
    }
    writeln();
}
(Not: Hem sol değerlerle hem de sağ değerlerle çalışabilsin diye auto ref yazdım.)

Ali
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4643 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Erdem'in söylediği türüne göre en uygun yöntem. Ben, nesne üyelerini başka dillerde olduğu gibi hemencecik yazdırıvermek için o kadar karmaşık bir yol düşündüm. Ama aslında o iş için write(zaman) bile çoğu durumda yeterli oluyor.

Ali
cos00kun #5
Üye Kas 2014 tarihinden beri · 262 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
evet sağolun aslında kitapta Yapı bölümünü zaten okudum. write(zaman) ile çözümüde biliyorum ancak benim tek amacım foreach ile bunları otomatik okutmaktı. Aslında itiraf etmeliyim amacım http://ddili.org/forum/post/12949 burdaki programı artık uygulamaya geçirerek bunu GtkD kütüphanesi yardımıyla tamamlamak tı  :blush:
yine itiraf edeyimki orda yazılan şu kısımda biraz tıkandım sanırım
.........
    auto entries = new Falcon4Entity[](adet);
    auto okunanEntries = dosya.rawRead(entries);
.........
ayrıca burada sanki sorduğumun cevabı var gibiydi.. Ben tüm anlattıklarınıza rağmen şöyle bir mantık düşündüm sanırım.. git dosyadan struct da belitilen değişkenlerin byte uzunlukları kadar değeri al ve struct değişkenlerine at bunları yaptıktan sonra yazdır..
Bu noktada tekrar o konulara ve yazılanlara bakıp biraz daha kurcalayayım bakalım.. eğer bir ilerleme kaydedemez yada anlayamazsam tekrar sorarım.. Eğer konuyu iyice kavrarsam GtkD topicğimde kaldığım yerden bu bahsettiğim programı yazarak devam ederim  :-)
E=mc^2
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4643 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Birinci satır, adet elemanı olan bir Falcon4Entity dizisi oluşturuyor. Şunun eşdeğeri:
    Falcon4Entity[] entries;
    entries.length = adet;
İkinci satır da dosyaya daha önce rawWrite ile yazılmış olduğu varsayılan Falcon4Entity dizisini yukarıda oluşturduğumuz dizinin elemanlarının üzerine okuyor.

rawWrite ve rawRead'i daha basit yapılarla denemeni öneririm. Bu yöntemin string üyeler için (veya başka türden dinamik dizi üyeler için) kullanılamadığını göreceksin. Sabit uzunluklu dizilerde sorun yoktur ve zaten o yüzden gösterdiğin konudaki örnekte byte[8] gibi sabit uzunluklu diziler kullanılıyor.

Ali
cos00kun #7
Üye Kas 2014 tarihinden beri · 262 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
tamamdır Ali hocam istediğim tüm cevapları aldım sağolun  :-)
E=mc^2
erdem (Moderatör) #8
Üye Tem 2009 tarihinden beri · 1076 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Ali hocanın gösterdiği kullanıma örnek de şu şekilde olabilir:
import std.stdio;
import std.format;
import std.random;
 
struct Saat
{
    this (uint saat, uint dakika, uint saniye)
    {
        this.saat_ = saat;
        this.dakika_ = dakika;
        this.saniye_ = saniye;
    }
 
    uint saat_;
    uint dakika_;
    uint saniye_;
 
    uint saat() const @property { return saat_; }
    uint dakika() const @property { return dakika_; }
    uint saniye() const @property { return saniye_; }
 
    string toString() const
    {
        return format!"%02s:%02s:%02s"(saat_, dakika_, saniye_);
    }
}
void main()
{
    auto birSaat = Saat(12, 15, 22);
    writeln(birSaat);
 
    Saat[] saatler;
    saatler.length = 19;
 
    foreach(saat; saatler)
    {
        saat = Saat(uniform!("[]")(0, 12), uniform!("[]")(0, 60), uniform!("[]")(0, 60));
        writeln(saat);
    }
}
cos00kun #9
Üye Kas 2014 tarihinden beri · 262 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Erdem hocam güzel çözüm olmuş teşekkürler
E=mc^2
acehreli (Moderatör) #10
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4643 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
saatler'in elemanlarının döngüden sonra bile hep 0:0:0 değerinde olmalarının nedeni, benim de hâlâ düştüğüm bir hata: foreach elemanları ref olarak almıyor. :) Şöyle değiştirilebilir:
    foreach(ref saat; saatler)
    {
        // ...
    }
Ali
kerdemdemir #11
Üye Eyl 2013 tarihinden beri · 168 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Coskun sorunu surda tartisilmis soruya benzettim benzer bir konuda calisiyor olabilirmisin?

http://ddili.org/forum/post/13012

Eger ayni ise ben soyle bir oneride bulunmustum :

struct ZamanFormati
{
    int saat;
    int dakika;
    int saniye;
    bool sabahMi;
};

char* timeConversion(char* s) {
    ZamanFormati zaman;
    zaman.sabahMi = s[strlen(s) - 2] == 'A';
    sscanf(s, "%2d : %2d : %2d", &zaman.saat, &zaman.dakika, &zaman.saniye);
    sprintf( s, "%02d:%02d:%02d", zaman.sabahMi ? zaman.saat % 12 : ((zaman.saat %12) + 12), zaman.dakika, zaman.saniye);
    return s;
}
cos00kun #12
Üye Kas 2014 tarihinden beri · 262 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Sağolun hepiniz..
evet benzer konular ama aslında benim daha öncede yazdığım gibi asıl amacım bir uçuş simülasyonu oyunundaki bir dosyada tutulan bazı verileri (binary dosya) alıp bir ListBox üzerinde bunları değiştirmek güncelmemek vesaire ( http://ddili.org/forum/thread/1764 )... Bu amaç için öncelikle Özellikle Erdem hocanın yardımlarıyla GtkD kütüphanesini öğreniyorum.. Açıkçası eh işte işlerimi görecek kadar bir yol aldım da. Şimdi Dosyadan bunları almak ve işlemekle ilgili D dilinde eksik kaldığım bölümlere odaklanıyorum.

 Burada bu verileri Bir yapı olarak belirlenmiş değişkenlere tek tek atamak lazım diye çıktık yola.. yani şöyle dosyadaki her 81 bytlık veriyi bir yapıda tanımladığım 81 adet değişkene atayacağım.. Şimdi bunu aslında yapmak çok zor değil dosyadan alıp byte olarak okutabiliyorum ancak ben bunu hiç uğraşmadan foreach() işlevinin otomatik olarak struct yapısındaki değişkenlere atamasını bekledim yani ben foreach() a al kardeşim yapı ismi şu diyecektim oda aslında yapının içindeki tüm değişkenleri sırayla döndürecekti ama işler umduğum gibi olmadı burda son yazılanları okuyana kadar  ;-)  yoksa yapıNesnesiİsmi.değişkenİsmi ile bunları zaten yaptırabiliyorum..

Sonuç olarak anladımki bazı yazılanları belki anlamak değil ama kavrayabilmek için D dilinde birazdaha ilerlemem ve Kitaptan okumaya devam etmem gerekiyor.. Bazan C++ de öğrendiklerim aslında birçok konunun benzer olmasına rağmen yaklaşım farklılıkları olması sebebiyle D dilinde herşeyi silbaştan Kavramak çok önemli ..

sevgi ve saygılarımla

Edit: Yukarıda  ".....81 adet değişkene atayacağım...." yazmışım bu yanlış çünkü bazı değişkenler ushort bazı değişkenler byte[8] .. o yüzden toplam 81 adet değişken yok. 81 adet byte belli sayıda Değişken var.. Bu düzeltmeyiğde ekleyeyeim  :blush:
E=mc^2
Bu mesaj cos00kun tarafından değiştirildi; zaman: 2018-01-19, 01:53.
cos00kun #13
Üye Kas 2014 tarihinden beri · 262 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
import std.stdio;
import std.string;
import std.file;
 
struct Falcon4 {
    short numEntities;
    ushort id;
    ushort collisionType;
    float collisionRadius;
    byte[8] classInfo;
    uint updateRate;
    uint updateTolerance;
    float fineUpdateRange;
    float fineUpdateForceRange;
    float fineUpdateMultiplier;
    uint damageSeed;
    int hitpoints;
    ushort majorRevisionNumber;
    ushort minorRevisionNumber;
    ushort createPriority;
    byte managementDomain;
    byte transferable;
    byte private_;
    byte tangible;
    byte collidable;
    byte global;
    byte persistent;
    byte[3] padding;
    short[7] visType;
    short vehicleDataIndex;
    byte dataType;
    uint dataPtr;
}
 
void main(string[] parametreler)
{
    File dosya = File ("FALCON4.ct", "rb" );
    Falcon4[1] falcon4;
    foreach(elemanlar;dosya.rawRead(falcon4[0..$])) {
        write(elemanlar);
    }
    dosya.close();
    readln();
}
aslında ben burada sadece foreach() işlevine biraz hayıflanıyorum :-) gariptirki Falcon4 yapısından türetilen falcon4 nesnesinin elemanlarını direkt olarak döndüremeyen foreach() , Aynı yapıdan dizi olarak üretilen falcon4 nesne dizisini döndürebiliyor.:-p   Sorun yok yola devam..
E=mc^2
cos00kun #14
Üye Kas 2014 tarihinden beri · 262 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
üstad bunu çözmüş (Ali hocam)  :-)  Buradan işi çözüyorum artık
import std.stdio;
import std.string;
import std.exception;
 
// Bkz: https://pmc.editing.wiki/doku.php?id=falcon4:file_formats:ct_file
 
align(1)
struct VuEntity {
    align(1):
    short numEntities;
    ushort id;
    ushort collisionType;
    float collisionRadius;
    byte[8] classInfo;
    uint updateRate;
    uint updateTolerance;
    float fineUpdateRange;
    float fineUpdateForceRange;
    float fineUpdateMultiplier;
    uint damageSeed;
    int hitpoints;
    ushort majorRevisionNumber;
    ushort minorRevisionNumber;
    ushort createPriority;
    byte managementDomain;
    byte transferable;
    byte private_;
    byte tangible;
    byte collidable;
    byte global;
    byte persistent;
    byte[3] padding;
}
 
// Denetleyelim
static assert (VuEntity.sizeof == 60);
 
align(1)
struct Falcon4Entity {
    align(1):
    VuEntity vuClassData;
    short[7] visType;
    short vehicleDataIndex;
    byte dataType;
    uint dataPtr;
}
 
// Denetleyelim
static assert ((Falcon4Entity[2]).sizeof == 81 * 2);
 
Falcon4Entity[] oku(string dosyaİsmi) {
    auto dosya = File(dosyaİsmi, "rb");
 
    short adet;
    auto okunanAdet = dosya.rawRead((&adet)[0..1]);
    enforce(okunanAdet.length == 1, "HATA: Adet değerini okuyamadım");
 
    writefln("%s adet nesne okuyorum", adet);
 
    auto entries = new Falcon4Entity[](adet);
    auto okunanEntries = dosya.rawRead(entries);
    enforce(okunanEntries.length == adet,
            format("HATA: %s yerine yalnızca %s nesne okudum", adet, okunanEntries.length));
    return entries;
}
 
int main(string[] args) {
    if (args.length != 2) {
        stderr.writefln("Kullanım: %s <dosya ismi>", args[0]);
        return 1;
    }
 
    Falcon4Entity[] entries = oku(args[1]);
 
    writefln("Elimde %s adet nesne var: %s", entries.length, entries);
 
    return 0;
}
E=mc^2
acehreli (Moderatör) #15
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4643 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Burada iki yakın konu oluştu: Birincisi, Coşkun'un sorunu olan falcon4 dosya düzenini okumak. Yukarıdaki koddaki bağlantıdaki bilgilere göre yazdığım yöntemin hataları olabilir ama temelde doğru: falcon4 nesneyi bellekten olduğu gibi yazıp okuduğundan rawRead ve rawWrite yöntemi kullanılıyor.

Daha genel olarak, üyeleri kaydedip tekrar okuma olayına serialization+deserialization deniyor. Bunu yapan bir kaç tane D modülü var. code.dlang.org'da "serialization" diye aratınca şunlar çıkıyor:

  http://code.dlang.org/search?q=serialization

Kendim için bir yöntem düşünsem ve okuma yazma olayının çok hızlı olması gerekmese (örneğin, yalnızca programın başında tek kere okunacaktır), ben o modüllerden birisini kullanırdım. Örneğin, nesne json veya yaml düzeninde yazdırıldığında metin düzenleyicimde açtığımda herşeyi basitçe görebilirdim ve gerektiğinde değiştirebilirdim.

Ek olarak, o modüllerin çoğunun __traits(allMembers), __traits(getMember), ve UDA olanaklarını kullandığından eminim.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  1  2  sonraki 
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2018-02-24, 02:19:38 (UTC -08:00)