#include #include #define URUN_NO_MIN 1 #define KAYIT_SAY 100 #define STOK_LIMIT_MIN 0 #define ALIS_FIYAT_MIN 0 #define LINK_AYNI -2 #define LINK_GONDER -3 /* Sabitler ve Anlamlari */ /* --------------------- */ /* URUN_NO_MIN : Ürün numarasının alabileceği en düşük değer. (negatif değeler özel parametre- lere karşılık gelebileceği için tercih edilmemelidir.) KAYIT_SAY : Hash fonksiyonu ile gidilecek, ilk başta yaratılan kısım. Bu değer oynanarak ilk başta ne kadar boş kayıt olacağı değiştirilebilir. DİKKAT: Dosyalar yaratıldıktan sonra bunu değiştirmeniz sorun çıkartır. STOK_LIMIT_MIN : Stok değerinin alabileceği minimum değerdir. Programda depoda olmayan bir ürünün satılamayacağı düşünülerek bu sabit 0 alınmıştır. Ancak stok değerinin - değer- lere de düşmesi isteniyorsa bu değer değiştirilebilir. ALIS_FIYAT_MIN : Birim alış/satış fiyatlarının alabileceği minimum değeri belirler. Bir ürünün en fazla bedava satılacağı (o da nedense) düşünülmüş ve programda 0 ayarlanmıştır. Ama eğer ürünü satıp üstüne de para verilmesi isteniyorsa bu değişken her türlü sayı yapılabilir. LINK_AYNI : urun_duzenle fonksiyonuna değiştirilen girdideki link değerinin değiştirilmemesi gerektiğini söyleyen sembolik sabittir. LINK_GONDER : urun_duzenle fonksiyonuna gönderildiğinde fonksyinonun urun_kodu ile gönderilen ürüne ait link değerini geri döndürmesini sağlar. */ /* Yapılar */ struct URUN_YAPI { int urun_kodu; char urun_adi[20]; float birim_alis_fiyati; int stok_miktari; int sonraki; int link; }; struct SATIS_YAPI { char fatura_no[6]; char satis_tarihi[6]; int satis_miktari; float birim_satis_fiyati; int sonraki; }; /* Kullanıcı tanımlı tipler */ typedef struct URUN_YAPI URUN; typedef struct SATIS_YAPI SATIS; void beklet() { /* Bu fonksiyonun tek amaci kullaniciyi bir tusa basana kadar bekletmek, ve sonra ekrani silmektir. */ printf("\nDevam etmek icin bir tusa basin."); getche(); system ("cls"); } int hash(int urun_kodu) { return (urun_kodu % KAYIT_SAY) + 1; } int urun_var_mi(int urun_kodu,int kayit_no, int link_yolla) { /* Ürünün olup olmadığını kontrol eder. Aşağıdaki değerlerden birini dönüdürür. */ /* 0: Urun yok. */ /* -1: Dosya açılamadı. */ /* -2: Urun var. */ FILE *fp; URUN oku; if ((fp=fopen ("urunler.dat","rb+"))== NULL) { printf("Urunler.dat acilamadi. Gidiyorum ben."); return -1; } if (kayit_no == -1) { /* Eğer fonksiyona ilk defa geldiysek hash ile asıl kaydı kontrol etmeliyiz. */ fseek(fp,(hash(urun_kodu) - 1) * sizeof(URUN),0); } else { fseek(fp,(kayit_no) * sizeof(URUN),0); /* Eğer fonksiyon kendini çağırdıysa dosya sonuna gidip bağlayacağız. */ } fread(&oku,sizeof(URUN),1,fp); if (oku.urun_kodu == urun_kodu) { fclose(fp); if (link_yolla == 0) { /* Eğer link numarasını gönderme parametresiyse çağrıldıysa */ return oku.link; } else { return -2; } } if (oku.urun_kodu == -1) { fclose(fp); return 0; } else { if (oku.sonraki == -1) { fclose(fp); return 0; } else { fclose(fp); return urun_var_mi(urun_kodu, oku.sonraki, link_yolla); } } } int urun_ekle(int urun_kodu, char urun_adi[20], float birim_alis_fiyati, int stok_miktari, int kayit_no) { /* Adı üstünde: Ürün ekler */ /* 0: Başarılı. */ /* -1: Dosya açılamadı. */ FILE *fp; URUN oku; int sayac; int gecici_konum; if ((fp=fopen ("urunler.dat","rb+"))== NULL) { printf("Urunler.dat acilamadi. Gidiyorum ben."); return -1; } if (kayit_no == -1) { /* Eğer fonksiyona ilk defa geliysek hash ile asıl kaydı kontrol etmeliyiz. */ fseek(fp,(hash(urun_kodu) - 1) * sizeof(URUN),0); } else { fseek(fp,kayit_no * sizeof(URUN),0); /* Eğer fonksiyon kendini çağırdıysa dosya sonuna gidip bağlayacağız. */ } fread(&oku,sizeof(URUN),1,fp); if (oku.urun_kodu == -1) { /* Burası boş, yazabiliriz. */ /* Gerekli atamalar */ oku.urun_kodu = urun_kodu; for (sayac=0;sayac<20;sayac++) { oku.urun_adi[sayac] = urun_adi[sayac]; } oku.birim_alis_fiyati = birim_alis_fiyati; oku.stok_miktari = stok_miktari; oku.sonraki = -1; oku.link = -1; fseek(fp,-sizeof(URUN),1); // Denetlemek için ileri gitmiştik, dön geri. fwrite(&oku,sizeof(URUN),1,fp); // ve büyülü satır... fclose(fp); } else { /* Bu kayıt dolu, hadi başka bulalım. */ /* Eğer bu kayıt bağlı listenin son kaydıysa bu kaydı sonraki kısmını değiştirerek yeniden yaz. */ if (oku.sonraki == -1) { gecici_konum = ftell(fp); fseek(fp,0,2); oku.sonraki = ftell(fp)/sizeof(URUN); fseek(fp,gecici_konum,0); fseek(fp,-sizeof(URUN),1); fwrite(&oku,sizeof(URUN),1,fp); /* Sonra yeni ekleneceği ekleyelim. */ fseek(fp,0,2); oku.sonraki = -1; oku.link = -1; oku.birim_alis_fiyati = birim_alis_fiyati; oku.stok_miktari = stok_miktari; oku.urun_kodu = urun_kodu; for (sayac=0;sayac<20;sayac++) { oku.urun_adi[sayac] = urun_adi[sayac]; } fwrite(&oku,sizeof(URUN),1,fp); fclose(fp); } else { /* eğer bağlı listenin son elemanı değilse onu bulana kadar aynı algoritmayı tekrarla */ fclose(fp); return urun_ekle(urun_kodu, urun_adi[20], birim_alis_fiyati, stok_miktari, oku.sonraki); } } return 0; } int urun_guncelle(int urun_kodu, float birim_alis_fiyati, int stok_miktari, int kayit_no, int link) { /* 0: Başarılı. */ /* -1: Dosya açılamadı. */ FILE *fp; URUN oku; if ((fp=fopen ("urunler.dat","rb+"))== NULL) { printf("Urunler.dat acilamadi. Gidiyorum ben."); return -1; } if (kayit_no == -1) { /* Eğer fonksiyona ilk defa geliysek hash ile asıl kaydı kontrol etmeliyiz. */ fseek(fp,(hash(urun_kodu) - 1) * sizeof(URUN),0); } else { fseek(fp,kayit_no * sizeof(URUN),0); /* Eğer fonksiyon kendini çağırdıysa dosya sonuna gidip bağlayacağız. */ } fread(&oku,sizeof(URUN),1,fp); if (oku.urun_kodu == urun_kodu) { /* İşte düzenlenecek ürünümüzü bulduk, mutluyuz biz. :) */ if (link == LINK_GONDER) { fclose(fp); return oku.link; } else { if (birim_alis_fiyati != ALIS_FIYAT_MIN - 1) { oku.birim_alis_fiyati = birim_alis_fiyati; } if (stok_miktari != STOK_LIMIT_MIN - 1) { oku.stok_miktari = stok_miktari; } if (link != LINK_AYNI) { oku.link = link; } fseek(fp,-sizeof(URUN),1); // Denetlemek için ileri gitmiştik, dön geri. fwrite(&oku,sizeof(URUN),1,fp); // ve büyülü satır... fclose(fp); } } else { /* Bu kayıt dolu, hadi başka bulalım. */ fclose(fp); return urun_guncelle(urun_kodu, birim_alis_fiyati, stok_miktari, oku.sonraki, link); } return 0; } int satis_ekle(int urun_kodu, char fatura_no[6], char satis_tarihi[6], int satis_miktari, float birim_satis_fiyati, int sonraki, int simdiki) { /* 0: Sorunsuz tamam */ /* -1: Dosya hatası */ FILE *fp; SATIS oku; int link_konum; int sayac; /* Önce urune bakalım... Eğer üründeki link -1 ise bu ürüne daha önce satış eklenmemiştir ki, ilk olduğu için işimiz çoooook basit olur. */ if (sonraki == -2) { /* Eğer fonksiyon kendini çağırmadıysa */ link_konum = urun_var_mi(urun_kodu,-1,0); if (link_konum == -1) { /* O zaman linki yaratacağız. */ if ((fp=fopen ("satislar.dat","rb+"))== NULL) { return -1; } fseek(fp,0,2); /* Dosya sonuna uç, ciiiik */ link_konum = (ftell(fp) / sizeof(SATIS)) + 1; for (sayac=0;sayac<6;sayac++) { oku.fatura_no[sayac] = fatura_no[sayac]; } for (sayac=0;sayac<6;sayac++) { oku.satis_tarihi[sayac] = satis_tarihi[sayac]; } oku.satis_miktari = satis_miktari; oku.birim_satis_fiyati = birim_satis_fiyati; oku.sonraki = -1; fwrite(&oku,sizeof(SATIS),1,fp); // ve büyülü satır... fclose(fp); urun_guncelle(urun_kodu, ALIS_FIYAT_MIN - 1, STOK_LIMIT_MIN - 1, -2, link_konum); /* Şu hayatta zaten ne oluyorsa iletişimsizlikten kaynaklanıyor. Bağlantıyı koparmamak lazım. urunler.dat ile satislar.dat da yukarıdaki satırla birbirine bağlanacak. */ } else { /* Eğer o ürüne dair daha önceden bir satış kaydı varsa bu biraz uğraştırıcı... Tüm kayıtları sıradan gezmeye başlayalım, uygun olan bağı bulalım ve hooop yeni satış bilgilerini yazalım. */ return satis_ekle(urun_kodu, fatura_no, satis_tarihi, satis_miktari, birim_satis_fiyati, link_konum, simdiki); } } else { if ((fp=fopen ("satislar.dat","rb+"))== NULL) { return -1; } fseek(fp,(sonraki-1) * sizeof(SATIS),0); fread(&oku, sizeof(SATIS),1,fp); if (sonraki == -1 || strncmp(oku.satis_tarihi,satis_tarihi,6) < 0) { /* Eğer girilen kayıt dosyadakinden daha büyükse işlem yapılacak */ /* Eğer sonraki != 0 AMA simdiki == -1 ise o zaman urunler.dat'dan ulaşılan ilk satışdayız demektir. Eğer yeni kaydedeceğimiz satış bu satıştan önce gelecekse o zaman urunler.dat'daki bağ da değişicek demektir ki işte bunun için bu özel şartı yerine getiren bir kod parçası yazacağım şimdi. */ for (sayac=0;sayac<6;sayac++) { oku.fatura_no[sayac] = fatura_no[sayac]; } for (sayac=0;sayac<6;sayac++) { oku.satis_tarihi[sayac] = satis_tarihi[sayac]; } oku.satis_miktari = satis_miktari; oku.birim_satis_fiyati = birim_satis_fiyati; oku.sonraki = sonraki; fseek(fp,0,2); /* Dosya sonuna ışınlan */ link_konum = (ftell(fp) / sizeof(SATIS)) + 1; fwrite(&oku,sizeof(SATIS),1,fp); if (simdiki == -1) { /* Önceki bağ düzelt */ fclose(fp); urun_guncelle(urun_kodu, ALIS_FIYAT_MIN - 1, STOK_LIMIT_MIN - 1, -2, link_konum); } else { fseek(fp,(simdiki-1) * sizeof(SATIS),0); fread(&oku, sizeof(SATIS),1,fp); fseek(fp,-sizeof(SATIS),1); oku.sonraki = link_konum; fwrite(&oku,sizeof(SATIS),1,fp); fclose(fp); } } else { /* Yok girilen kayıt dosyadakinden daha büyük değilse bir sıkıntı yok, taramaya devam... */ return satis_ekle(urun_kodu, fatura_no, satis_tarihi, satis_miktari, birim_satis_fiyati, oku.sonraki, sonraki); } } return 0; } int satis_listele(int urun_kodu, char ust_limit[6], char alt_limit[6]) { /* 0: Başarılı. */ /* -1: Dosya açılamadı. */ FILE *fp; SATIS oku; int sayac=0; int konum; printf("%d numarali urunun satis listesi\n",urun_kodu); printf("\n"); printf(" NO FATURA NO SATIS TARIHI SATIS MIKTARI BIRIM SATIS FIYATI\n"); printf("---- --------- ------------ ------------- ------------------\n"); konum = urun_guncelle(urun_kodu, ALIS_FIYAT_MIN-1,STOK_LIMIT_MIN-1,-1,LINK_GONDER); if (konum == -1) { printf("(hic satis kaydi yok.)\n"); return 0; } if ((fp=fopen ("satislar.dat","rb+"))== NULL) { return -1; } while (konum != -1) { fseek(fp,(konum-1) * sizeof(SATIS),0); fread(&oku,sizeof(SATIS),1,fp); konum = oku.sonraki; if (strncmp(oku.satis_tarihi,alt_limit,6) >= 0 && strncmp(oku.satis_tarihi,ust_limit,6) <= 0 && oku.fatura_no[0] != '|') { sayac++; printf("%4d %c%c%c%c%c%c %c%c%c%c%c%c %13d %18.4f \n",sayac,oku.fatura_no[0],oku.fatura_no[1],oku.fatura_no[2],oku.fatura_no[3],oku.fatura_no[4],oku.fatura_no[5],oku.satis_tarihi[0],oku.satis_tarihi[1],oku.satis_tarihi[2],oku.satis_tarihi[3],oku.satis_tarihi[4],oku.satis_tarihi[5],oku.satis_miktari,oku.birim_satis_fiyati); } } fclose(fp); } int satis_sil(int urun_kodu, char fatura_no[6]) { /* 1: Öyle bir fatura no yok */ /* 0: Başarılı. */ /* -1: Dosya açılamadı. */ FILE *fp; SATIS oku; int konum; konum = urun_guncelle(urun_kodu, ALIS_FIYAT_MIN-1,STOK_LIMIT_MIN-1,-1,LINK_GONDER); if (konum == -1) { return 1; } if ((fp=fopen ("satislar.dat","rb+"))== NULL) { return -1; } while (konum != -1) { fseek(fp,(konum-1) * sizeof(SATIS),0); fread(&oku,sizeof(SATIS),1,fp); konum = oku.sonraki; if (strncmp(oku.fatura_no,fatura_no,6) == 0) { /* EVET! Silinecek faturayı bulduk!!!!! */ fseek(fp,-sizeof(SATIS),1); oku.fatura_no[0] = '|'; fwrite(&oku,sizeof(SATIS),1,fp); fclose(fp); return 0; } } fclose(fp); return 1; } void listele() { /* Bu fonksiyon kontrol için, asıl programda işe yaramaz. */ FILE *fp; URUN urun; int sayac=0; int gecici; if ((fp=fopen ("urunler.dat","rb+"))== NULL) { printf("Urunler.dat acilamadi. Gidiyorum ben."); return -1; } fseek(fp,0,2); gecici = ftell(fp)/sizeof(URUN); printf("Kayit sayisi: %d\n\n", gecici); fseek(fp,0,0); for (sayac=1;sayac<=gecici;sayac++) { fread(&urun,sizeof(URUN),1,fp); printf("%3d %4d %20s %6.2f %2d %4d %2d\n",sayac,urun.urun_kodu,urun.urun_adi,urun.birim_alis_fiyati,urun.stok_miktari, urun.sonraki, urun.link); } fclose(fp); } void listele2() { /* Bu fonksiyon kontrol için, asıl programda işe yaramaz. */ FILE *fp; SATIS urun; int sayac=0; int gecici; if ((fp=fopen ("satislar.dat","rb+"))== NULL) { printf("satislar.dat acilamadi."); return -1; } fseek(fp,0,2); gecici = ftell(fp)/sizeof(SATIS); printf("Kayit sayisi: %d\n\n", gecici); fseek(fp,0,0); for (sayac=1;sayac<=gecici;sayac++) { fread(&urun,sizeof(SATIS),1,fp); printf("%3d %c%c%c%c%c%c %c%c%c%c%c%c %5d %6.2f %2d\n",sayac,urun.fatura_no[0],urun.fatura_no[1],urun.fatura_no[2],urun.fatura_no[3],urun.fatura_no[4],urun.fatura_no[5],urun.satis_tarihi[0],urun.satis_tarihi[1],urun.satis_tarihi[2],urun.satis_tarihi[3],urun.satis_tarihi[4],urun.satis_tarihi[5],urun.satis_miktari,urun.birim_satis_fiyati,urun.sonraki); } fclose(fp); } int main() { /* Acilis yazilari BASLANGICI */ printf("Umut BENZER\n"); printf("05-06-7670\n"); printf("Ege Universitesi Bilgisayar Muhendisligi 1. Sinif\n"); printf("http://www.ubenzer.com\n"); printf("Odev 4 (0.1)\n\n"); /* Acilis yazilari SONU */ int sag_serbest=-1; int sayac; int girdi; char girdi2[20]; float girdi3; int girdi4; char girdi5[6]; char girdi6[6]; char secenek; /* Girdi degiskenleri main fonksiyonun her bir yerinde farkli farkli bir sürü amaçla kullanıldığı için özel isimler vermedim. */ /* Dosyayi sifirdan yaratalim */ /* Odev kontrolunde kolaylik saglamasi acisindan dosyanin her acilista silinmesi ve tekrar yaratilmasi istendi. Programin gerceginde bunun iptal edilmesini saglamak icin asagidaki satirlar comment yapilabilir. */ FILE *fp; URUN yaz={-1,"",0,0,-1,-1}; remove ("urunler.dat"); // Eğer dosyalar varsa silinir. remove ("satislar.dat"); // Eğer dosyalar varsa silinir. if ((fp=fopen ("urunler.dat","w+b"))== NULL) { printf("Urunler.dat yaratilamadi. Gidiyorum ben."); return 0; } for (sayac=0;sayac