folder Tahribat.com Forumları
linefolder C - C++
linefolder C'de Dosyalama(Yardım)



C'de Dosyalama(Yardım)

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    wasd
    wasd's avatar
    Kayıt Tarihi: 14/Haziran/2006
    Erkek

     

    #include<stdio.h>
    #include<locale>
    
    	FILE *dsy;
    	char TCNo[11];
    	char ad[20];
    	char soyad[20];
    	char odaNo[10];
    	char tarih[11];
    	int giris=0;
    
    int main()
    {
    	//Türkçe karakterler
    	setlocale(LC_ALL,"TURKISH");
    	//Dosya oluşturma & açma
    	dsy = fopen("hastalistesi.dat","a+");
    	//Menü
    	while((giris!=5))
        {
        printf("      MENÜ\n----------------\n[1]Kayıt ekle\n[2]Kayıt düzenle\n[3]Kayıt sil\n[4]Kayıt bul\n[5]Çıkış\n");
        scanf("%d",&giris);
        if(giris==5)
        {
            break;
        }
    	else if(giris==1)
    	{
    		printf ("T.C. No:\n");
    		fgets (TCNo,11,stdin);
    		fputs (TCNo,dsy);
    		printf ("Ad:\n");
    		fgets (ad,20,stdin);
    		fputs (ad,dsy);
    		printf ("Soyad:\n");
    		fgets (soyad,20,stdin);
    		fputs (soyad,dsy);
    		printf ("Oda No:\n");
    		fgets (odaNo,10,stdin);
    		fputs (odaNo,dsy);
    		printf ("Tarih:\n");
    		fgets (tarih,11,stdin);
    		fputs (tarih,dsy);
    		fclose (dsy);
    	}
    	else if(giris==2)
    	{
    		fclose (dsy);
    	}
    	else if(giris==3)
    	{
    		fclose (dsy);
    	}
    	else if(giris==4)
    	{
    		fclose (dsy);
    	}
        else
    		printf("Yanlış giriş!!!\n\n");
        }
    }

     

    --------------------------------------------------------------

    Yazdığım kod henüz bu kadar.Önümde 2 hafta falan var daha teslim etmek için.Zaman bol olunca sallaya sallaya yapıyorum tabi işin aslı :D eksiklerimde var ayrıca,işin içinden tam çıkamıyorum...Şimdi bu kodlar hastalistesi.dat dosyasını oluşturup kayıt yapıyo ama her değişken bir alt satıra kayıt oluyo. Ve bir problemde şu ki ben arama yaptırdığım zaman bulunan tc kimlik no değerine ait tüm bilgiler gelmeli ama nasıl olacak? Birde kodları çalıştırırsanız görürsünüz,tc no sormadan direk ad soruyo. Bunları nasıl halledebilirim,bi yol gösterin :/


    :)
  2. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Tugberk
    Tugberk's avatar
    Kayıt Tarihi: 04/Ekim/2009
    Erkek

    Öncelikle son sorunun sebebi şu, scanf veri okurken enter tuşunu (\n) okumaz, doğal olarak bu stdin de kalır, sonraki fonksiyon, scanf , fgets vb veri okumaya kalktığında bu \n karakterini görür ve onu okuyarak sonlanır. Bu karakteri stdin den silmek için çeşitli yollar var, mesela fflush fonksiyonu kullanılır genelde ancak input stream için bu fonksiyon tanımsız davranışlıdır (undefined behavior), yani tüm derleyiciler bu fonksiyon ile stdin buffer ini boşaltmana izin verir ancak standartlarca garanti edilmez. Bu yüzden diğer yöntemlerden birisini kullan, scanf den sonra, getchar ile o karakteri oku ve buffer i boşalt.

    ... 

    scanf("%d",&giris);

    getchar();

    ...

    Altalta yazma meselesine gelince, bu fgets ile ilgili, scanf in aksine fgets girişten veriyi okuduktan sonra enter tuşunu da (\n) okur, doğal olarak stringin sonunda bu karakterde olur. sen bunu dosyaya yazdığın zaman doğal olarak sonraki veri bir alt satırdan başlar.

    Aslında bu iyi bişey, çünkü verileri yan yana tutarsan, ayraç olarak boşluk kullanmak zorundasın ve dosyadan okuma için fscanf kullanmalısın. fscanf boşluğa göre verileri ayıracak ama mesela iki isimli (ali osman gibi) kişilerde bu sorun olur. 

    Aramayı senin kodu etkilemeden şu şekilde yazabilirim, fseek ile dosya başına konumlan, counter 5 in katı ise, o okunan veri tc no dur. her veri okumada counter i bir arttır, tc no yu okuduğunda aranan ile strcmp kullanarak karşılaştır, aynı ise bulundu yaz ve sonraki 4 veriyi de ekrana yaz. counter e -1 koy ve döngüden çık. döngüden 2 şekilde çıkılabilir, ya dosya sonlanır, ya da kayıt bulunmuştur, kayıt bulunduysa counter -1 dir, aksi halde pozitif bir sayı. döngü sonunda counter in değerine göre döngüden ne şekilde çıkıldığı anlaşılabilir ve eğer kayıt bulunamamışsa (counter != -1) bulunamadı yazılır.

    kodu yazmadan önce bir kaç tavsiye.

    - Eğer yapıları gördüyseniz kullanıcı bilgilerinin hepsini tek bir yapı içinde tut. 

    - fonksiyonları gördüyseniz kullanıcı seçeneğini girdiğinde yapılacak olan işi ayrı bir fonksiyon olarak yaz ve yapı adresini parametre olarak yolla.

    - dosyayı binary olarak aç, yapının toplam boyutuna göre kaydı dosyadan fread ile oku ve okunan veri doğrudan yapıya aktarılsın. 

    - her seçenekten sonra dosyayı açıp kapama yapma, birkez aç ve kayıttan sonra fflush ile bufferi boşaltarak tüm verinin diske yazılmasını sağla.

    - karakter dizilerini 10-20 baytlık yapma en az 128 olsun, mesela tc no 11 hane, eğer 9 hane girersek \n i de alıyor ve dosyaya yazıyor, ancak 11 hane girersek sadece tam olarak tc no yu alıyor ve sonraki girdi dosyada tc no ile bitişik oluyor. fgets de pek kaliteli bir fonksiyon sayılmaz. (cogu standart C fonksiyonu gibi)

    kod : 

    #include <stdio.h>
    
    	FILE *dsy;
    	char TCNo[128];
    	char ad[128];
    	char soyad[128];
    	char odaNo[128];
    	char tarih[128];
    	int giris=0;
    
    int main()
    {
    	//Dosya oluşturma & açma
    	dsy = fopen("hastalistesi.dat","a+");
    	//Menü
    	while((giris!=5))
        {
            printf("      MENU\n----------------\n[1]Kayit ekle\n[2]Kayit duzenle\n"
                        "[3]Kayit sil\n[4]Kayit bul\n[5]Cikis\n");
            scanf("%d",&giris);
            getchar(); // dikkat
            
            if(giris==5)
            {
                break;
            }
        	else if(giris==1)
        	{
        		printf ("T.C. No\t: ");
        		fgets (TCNo,11,stdin);
        		fputs (TCNo,dsy);
        		printf ("Ad\t: ");
        		fgets (ad,20,stdin);
        		fputs (ad,dsy);
        		printf ("Soyad\t: ");
        		fgets (soyad,20,stdin);
        		fputs (soyad,dsy);
        		printf ("Oda No\t: ");
        		fgets (odaNo,10,stdin);
        		fputs (odaNo,dsy);
        		printf ("Tarih\t: ");
        		fgets (tarih,11,stdin);
        		fputs (tarih,dsy);
        		fflush(dsy); // dikkat.
        	}
        	else if(giris==2)
        	{
        		fclose (dsy);
        	}
        	else if(giris==3)
        	{
        		fclose (dsy);
        	}
        	else if(giris==4)
        	{
                char tmp[128] , tc[128];
                int counter = 0;
                
                fseek(dsy,0,SEEK_SET); // dosya basina konumlan
                printf("aranacak tc no: ");
                fgets(tc,sizeof(tc),stdin);
                
                while(!feof(dsy)) // dosya sonuna gelindi mi?
                {
                    fgets(tmp,sizeof(tmp),dsy); // dosyadan satir oku
                    
                    if( counter++ %5 == 0) 
                    {
                        if(!strcmp(tc,tmp)) // tc kimlik no bu mu
                        {
                            printf("--Bulundu--\a\n");
                            printf("Ad\t: %s",fgets(tmp,sizeof(tmp),dsy));
                            printf("Soyad\t: %s",fgets(tmp,sizeof(tmp),dsy));
                            printf("Oda No\t: %s",fgets(tmp,sizeof(tmp),dsy));
                            printf("Tarih\t: %s",fgets(tmp,sizeof(tmp),dsy));
                            printf("\n\n");
                            counter = -1; // bulundu
                            break;
                        }
                    }
                }
                if(counter != -1) // donguden ne sekile cikildi
                {
                    printf("Bulunamadi!\a\n\n");
                }
                fseek(dsy,0,SEEK_END);
        	}
            else
        		printf("Yanlış giriş!!!\n\n");
        }
    }
    

  3. KısayolKısayol reportŞikayet pmÖzel Mesaj
    wasd
    wasd's avatar
    Kayıt Tarihi: 14/Haziran/2006
    Erkek

    Çok sağol demek istediklerini anladım.

    EDİT: string.h ekleyince sorun düzeldi.verdiğin kodlarda arama işi tamam ama kayıtta haala sorun var tcden sonra ad ve soyadı birlikte soruyo,değerlerden biri null oluyo bu seferde bi sonraki kayıdın bilgileriyle karışıyo önceki kayıt. Çözmeye çalışıcam...


    :)
  4. KısayolKısayol reportŞikayet pmÖzel Mesaj
    tuncaxxz
    tuncaxxz's avatar
    Kayıt Tarihi: 23/Ağustos/2005
    Erkek

        #include<stdio.h> 
        #include<locale> 
         
            FILE *dsy; 
            char TCNo[11]; 
            char ad[20]; 
            char soyad[20]; 
            char odaNo[10]; 
            char tarih[11]; 
            int giris=0; 
         
        int main() 
        { 
            //Türkçe karakterler 
            setlocale(LC_ALL,"TURKISH"); 
           
            //Menü 
            while((giris!=5)) 
            { 
            printf("      MENÜ\n----------------\n[1]Kayıt ekle\n[2]Kayıt düzenle\n[3]Kayıt sil\n[4]Kayıt bul\n[5]Çıkış\n"); 
            scanf("%d",&giris); 
            if(giris==5) 
            {              break; 
            } 
            else if(giris==1) 
            { 
                
                 //Dosya oluşturma & açma 
                dsy = fopen("hastalistesi.dat","a+"); 
                printf ("T.C. No:\n"); 
                scanf("%s",&TCNo);
                fprintf(dsy,"%s ",TCNo);
                printf ("Ad:\n"); 
                scanf("%s",&ad);
                fprintf(dsy,"%s ",ad); 
                printf ("Soyad:\n"); 
                scanf("%s",&soyad);
                fprintf(dsy,"%s ",soyad); 
                printf ("Oda No:\n"); 
                scanf("%s",&odaNo);
                fprintf(dsy,"%s ",odaNo); 
                printf ("Tarih:\n"); 
                scanf("%s",&tarih); 
                fprintf(dsy,"%s\n",tarih);  
                fclose (dsy); 
            } 
            else if(giris==2) 
            { 
                 //Dosya oluşturma & açma 
                dsy = fopen("hastalistesi.dat","a+");
                fclose (dsy); 
            } 
            else if(giris==3) 
            { 
                 //Dosya oluşturma & açma 
                dsy = fopen("hastalistesi.dat","a+");
                fclose (dsy); 
            } 
            else if(giris==4) 
            { 
                 //Dosya oluşturma & açma 
                dsy = fopen("hastalistesi.dat","a+");
                fclose (dsy); 
            } 
            else 
                printf("Yanlış giriş!!!\n\n"); 
            } 
        }

     

     

    ----------------------

    hocam kodlarda oynama yaptım biraz. umarım fputs ve fgets stdin ile yapman gerekmiyordur bunu.  fopenları her case in başına koydum çünkü sadece program ilk açıldığında dosyanı çağırırsın. case bittikten sonra kapanır döngünün dışında açıldığı için bir daha işlem yapılamaz.

    sanırsam kayıt bulmayı olayında da string.h kütüphanesine ihtiyacın olacak. onu çağırman lazım


    punto cero
  5. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Tugberk
    Tugberk's avatar
    Kayıt Tarihi: 04/Ekim/2009
    Erkek

    Benim verdiğim kodu hem mingw hem visual C++ ile derledim, kayıtta herhangi bir sıkıntı yok, scanf den kaynaklanan sorunu ve çözümünü ilk mesajda göstermiştim zaten, scanf \n karakterini girişte bıraktığı için TC no isteyen fgets, \n karakterini girişten alıp direkt sonlanıyor ve sonraki fgets çağırılıyordu, girişi boşaltman için getchar kullanmanı önermiştim, (fflush input streams için güvenli değildir.) benim verdiğim kodu birebir kopyalayıp dener misin?

  6. KısayolKısayol reportŞikayet pmÖzel Mesaj
    wasd
    wasd's avatar
    Kayıt Tarihi: 14/Haziran/2006
    Erkek

    Tugberk bunu yazdı:
    -----------------------------

    Benim verdiğim kodu hem mingw hem visual C++ ile derledim, kayıtta herhangi bir sıkıntı yok, scanf den kaynaklanan sorunu ve çözümünü ilk mesajda göstermiştim zaten, scanf \n karakterini girişte bıraktığı için TC no isteyen fgets, \n karakterini girişten alıp direkt sonlanıyor ve sonraki fgets çağırılıyordu, girişi boşaltman için getchar kullanmanı önermiştim, (fflush input streams için güvenli değildir.) benim verdiğim kodu birebir kopyalayıp dener misin?


    -----------------------------

    string.h kütüphanesini eklemeden derlenmiyo,onuda ekleyerek derledim sonuç bu. visual studio 2010 ultimate kullanıyorum. devc++ ta da denedim ama strcmp fonksiyonu yüzünden o da hata veriyo.


    :)
  7. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Tugberk
    Tugberk's avatar
    Kayıt Tarihi: 04/Ekim/2009
    Erkek

    Sen tc kimlik nosunu alırken 11 karakter girmişsin, sorun şu, fgets fonksiyonu, ikinci parametresindeki değer yeterli ise, \n dahil girişteki tüm veriyi okuyup stringe aktarır. Ancak sen girişi 11 karakter ile sınırlamışsın fgets de, bende kaynak koda ekleme yaptım, bu fgets sorununu yukarıdaki önerilerde belirttim ve kendi eklediğim bölümde fgets i doğru kullandım, ancak senin yazdığın bölümü editlemeyi unutmuşum.

    Özetle yapman gereken, fgets in ikinci parametresini sizeof(string) olarak değiştirmek . Aksi halde fgets girişten 11 karakter okuyor(aslında 12 var \n ile beraber) ve dönüyor. Bir sonraki fgets yine o karakteri yani \n i okuyarak dönüyor. Ne yazıkki C de string fonksiyonları ya çok güvensizdir, yani string boyutunu aştığınızda güvensiz bellek alanına veri yazar, ya da fgets de olduğu gibi 2. parametrede verilen üst limitten sonrasını okumaz girişte bırakır. İkisi de çok kötü bir yöntem. C de girilen veriye göre genişleyen bir string fonksiyonu henüz yok .

  8. KısayolKısayol reportŞikayet pmÖzel Mesaj
    wasd
    wasd's avatar
    Kayıt Tarihi: 14/Haziran/2006
    Erkek

    Çok sağol,dediğin gibi sizeof(değişkenadı) yapınca tüm sorunlar halloldu :) anlattığın şeyler için çok sağol,derslerde yada her forumda görebileceğimiz türden şeyler değiller.Ayrıca soket programlama dökümanın da çok iyi,ordada yazdığın gibi soket programlamayla ilgili fazla bi bilgi yok olanlarda da pek bişey yok.


    :)
  9. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Tugberk
    Tugberk's avatar
    Kayıt Tarihi: 04/Ekim/2009
    Erkek

    wasd bunu yazdı:
    -----------------------------

    Çok sağol :) yani buradan anlayacağımız şey "Yaşasın c#" :D anlattığın şeyler için çok sağol,derslerde yada her forumda görebileceğimiz türden şeyler değiller.Ayrıca soket programlama dökümanın da çok iyi,ordada yazdığın gibi soket programlamayla ilgili fazla bi bilgi yok olanlarda da pek bişey yok.


    -----------------------------

    O döküman yüzünden çok kişi ekliyor ama üzerindeki tarihten daha eski bir döküman ve içinde ufak defek hatalar var. Ayrıca artık blocking socket fonksiyonları profesyonel yazılımlarda kullanılmıyor, tabi başlangıç için ideal. bende I/O completion port gibi yöntemler üzerinde çalışıyorum şu sıralar :) 

  10. KısayolKısayol reportŞikayet pmÖzel Mesaj
    wasd
    wasd's avatar
    Kayıt Tarihi: 14/Haziran/2006
    Erkek

    Araştırılması gereken şeyler,ama 3 ayda bir dil değiştirilince dili tamamıyla öğrenmek imkansız oluyo :/ zamanla olucak benden de bişeyler inşallah...şimdi anlattıklarını iyice bi anlayıp sindireyim :)


    :)
Toplam Hit: 1554 Toplam Mesaj: 10