> Geçici Dosyalar: Programın çalışması sırasında belli bir amaçla oluşturulan ve amaca ulaşıldıktan sonra silinen kısa ömürlü dosyalara Geçici Dosyalar denmektedir. Geçici Dosya oluşturulurken karşılaşabileceğimiz önemli bir sorun, bu dosyalara vereceğimiz ismin çakışmasıdır. İşte bu problemin çözümü için iki adet standart C fonksiyonu geliştirilmiştir. Bunlar "tmpfile" ve "tmpnam". Şimdi de bunları inceleyelim: >> "tmpfile" fonksiyonu: Olmayan bir isimle bir dosyayı "wb+" modunda oluşturur. Fonksiyonun prototipi aşağıdaki gibidir: #include FILE *tmpfile(void); Fonksiyon başarı durumunda oluşturulan dosyaya ilişkin "FILE" türünden yapının adresini döndürür. Hata durumunda ise "NULL" ile geri döner. Bu fonksiyon ile açılan geçici dosyalar, "fclose" çağrısı sonrasında veya programın sonlanmasıyla kapatılırlar. * Örnek 1, #include #include int main(void) { /* # OUTPUT # */ FILE* f; if ((f = tmpfile()) == NULL) { fprintf(stderr, "cannot create temporary file...\n"); exit(EXIT_FAILURE); } int i; for (i = 0; i < 100000; ++i) if (fwrite(&i, sizeof(int), 1, f) != 1) { fprintf(stderr, "cannot write to temporary file...\n"); exit(EXIT_FAILURE); } rewind(f); int value; while (fread(&value, sizeof(int), 1, f) == 1) printf("%d\n", value); if (ferror(f)) { fprintf(stderr, "cannot read from temporary file...\n"); exit(EXIT_FAILURE); } fclose(f); return 0; } >> "tmpnam" fonksiyonu: Bu fonksiyon bizlere bir yol ifadesi verir. Fakat bu yol ifadesini kullanarak bir dosya açmaz. Programcılar bu fonksiyon ile elde ettikleri yol ifadesinde belirtilen dosyayı açmakla yükümlüdürler. Fonksiyonun prototipi şu şekildedir: #include char *tmpnam(char *s); Fonksiyon parametre olarak elde edilecek yol ifadesinin yazılacağı alanın başlangıç adresini alır. Bu alanın yeterli uzunlukta olması bizim sorumluluğumuzdadır. "L_tmpnam" sembolik sabiti, iş bu alanın olması gerektiği maksimum büyüklük bilgisidir. NULL adres geçilmesi durumunda, fonksiyonun bünyesindeki statik ömürlü dizinin adresini bize döndürürler. Bu fonksiyonun üreteceği isim %100 biçimde "unique" olması garanti değildir. Dolayısıyla belli bir şeyden sonra fonksiyon başarısız olabilir. Fonksiyon başarısız olduğunda "NULL" değerine, başarılı olduğunda da ilgili ismin bulunduğu adresi verir. * Örnek 1, Aşağıdaki program UNIX türevi bir işletim sisteminde çalıştırılmıştır. Komut satırı argümanı olarak belirtilen dosyadaki "#" karakterlerini silmektedir. #include #include #include #include #define MAX_LINE 4096 bool is_sharped(const char* string); int main(int argc, char** argv) { /* # OUTPUT # */ /* Programa geçilen komut satırı argümanları kontrol ediliyor. */ if (2 != argc) { fprintf(stderr, "wrong number of arguments!...\n"); exit(EXIT_FAILURE); } /* Esas dosyayı açıyoruz. */ FILE* f_source; if((f_source = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "cannot open file: %s\n", argv[1]); exit(EXIT_FAILURE); } /* Geçici Dosya için bir isim elde ediyoruz. */ char* t_path; if((t_path = tmpnam(NULL)) == NULL) { fprintf(stderr, "cannot get temporary file name!...\n"); exit(EXIT_FAILURE); } /* Elde ettiğimiz o isimle Geçici Dosyayı açıyoruz. */ FILE* f_temp; if((f_temp = fopen(t_path, "w")) == NULL) { fprintf(stderr, "cannot open temporary file\n"); exit(EXIT_FAILURE); } /* * Daha sonra esas dosyayı satır satır okuyoruz. * Her bir satırı da işleyip, "buffer" alanına yazıyoruz. * En sonunda da işlenmiş halini Geçici Dosyaya yazıyoruz. */ char buffer[MAX_LINE]; while(fgets(buffer, MAX_LINE, f_source) != NULL) { if(!is_sharped(buffer)) { if(fputs(buffer, f_temp) == EOF) { fprintf(stderr, "cannot write temporary file\n"); goto FAILED; } } } /* Esas dosyadan okuma yaparken bir hatanın olup olmadığı kontrol ediliyor. */ if(ferror(f_source)) { fprintf(stderr, "cannot read file: %s\n", argv[1]); goto FAILED; } /* Daha sonra her iki dosya da kapatılıyor. */ fclose(f_source); fclose(f_temp); /* Esas dosyayı siliyoruz. */ if(remove(argv[1])) { fprintf(stderr, "cannot remove file: %s\n", argv[1]); goto FAILED; } /* En sonunda da Geçici Dosyanın ismini değiştiriyoruz. */ if(rename(t_path, argv[1])) { fprintf(stderr, "cannot rename file: %s\n", argv[1]); goto FAILED; } printf("Ok...\n"); return EXIT_SUCCESS; FAILED: /* Eğer herhangi bir hata oluşursa da oluşturulan Geçici Dosya da kapatılıp siliniyor. */ fclose(f_temp); if(remove(t_path)) { fprintf(stderr, "cannot delete temporary file!...\n"); exit(EXIT_FAILURE); } printf("Failed...\n"); return EXIT_FAILURE; } bool is_sharped(const char* string) { while(isspace(*string)) ++string; return *string == '#'; }