Bu proje, bir dosyadan (veya standart girdi akışından) satır satır veri okumanızı sağlayan
get_next_line fonksiyonunu içerir. Standart C fonksiyonlarından biri olan
read ile elde edilen verileri geçici bir alanda (stash) tutarak, her satırın
eksiksiz biçimde döndürülmesini amaçlar. Böylece tek seferde satırın tümünü yakalayabilir
ve birden çok dosyayı aynı anda yönetebilirsiniz.
\n ) kadar olan
kısmı döndürür.BUFFER_SIZE değerleri ile kullanılabilir.get_next_line(int fd): Projenin ana fonksiyonudur. Dosyadan okur, satır sonuna
gelindiğinde satırı döndürür, stash yapısını günceller.ft_copy_to_stash: Okunan veriyi stash olarak adlandırdığımız
statik string alanına ekler.ft_have_nl: Satır sonu karakteri ( \n ) var mı, kontrol eder.ft_extract_line: stash içerisinden bir satırı koparıp
döndürür.ft_recreate_stash: Okunmuş satırdan kalan kısımla stash
yapısını yeniden oluşturur.ft_strlen, ft_strdup, ft_strjoin,
ft_substr,
ft_free_stash gibi yardımcı fonksiyonları barındırır.
char *get_next_line(int fd);fd: Okuma yapılacak dosyanın tanımlayıcısı (File Descriptor).
char *
döndürür. Dosyanın sonuna gelinmişse veya hata varsa NULL döner.
char *get_next_line(int fd)
{
char buf[BUFFER_SIZE + 1];
long bytes_read;
static char *stash = NULL;
char *line;
line = 0;
bytes_read = BUFFER_SIZE;
if (fd < 0 || BUFFER_SIZE <= 0)
return (ft_free_stash(&stash, 0));
while (bytes_read > 0)
{
bytes_read = read(fd, buf, BUFFER_SIZE);
if ((bytes_read <= 0 && !stash) || bytes_read == -1)
return (ft_free_stash(&stash, 0));
buf[bytes_read] = '\0';
stash = ft_copy_to_stash(stash, buf);
if (ft_have_nl(stash))
{
line = ft_extract_line(stash);
if (!line)
return (ft_free_stash(&stash, 0));
return (stash = ft_recreate_stash(stash), line);
}
}
return (ft_free_stash(&stash, 1));
}
Açıklama: Fonksiyon, dosyadan read ile okunan verileri
stash adlı
statik değişkende biriktirir. Satır sonu karakterine (\n) rastlandığında,
bu satırı kopararak döndürür ve stash kalan metinle güncellenir.
stash içeriğinden okunan satırı çıkarıp,
geriye kalan veriyi yeni bir stash olarak saklamak için kullanılır.
static char *ft_recreate_stash(char *stash);stash: Satır verisini geçici olarak tutan bellek alanı.
stash değeri. Hata
durumunda veya
verinin devamı yoksa NULL döner.
static char *ft_recreate_stash(char *stash)
{
size_t i;
char *res;
i = 0;
if (!stash)
return (NULL);
while (stash[i] != '\n')
i++;
if (stash[i + 1] == '\0')
return (ft_free_stash(&stash, 0));
res = ft_substr(stash, i + 1, ft_strlen(stash));
if (!res)
{
ft_free_stash(&stash, 0);
return (NULL);
}
ft_free_stash(&stash, 0);
return (res);
}
Açıklama: Fonksiyon, mevcut stash içerisindeki veriyi analiz eder; satır
sonu karakterine (\n) kadar olan kısmı okunan satır olarak ayırır ve geriye kalan kısmı
yeni bir stash olarak yeniden oluşturur. Böylece, sonraki okuma işlemlerinde eksik veri
kalmadan devam edilebilir. Hata durumunda veya verinin tamamı okunduğunda uygun şekilde
NULL döner.
stash içerisinden okunan satırı, satır sonu
karakterini de dahil ederek ayırıp yeni bir string oluşturur.
static char *ft_extract_line(char *stash);stash: Okunan veriyi geçici olarak saklayan string.stash durumunda 0 döner.
static char *ft_extract_line(char *stash)
{
char *line;
size_t i;
size_t j;
i = 0;
if (!stash)
return (0);
while (stash[i] != '\n')
i++;
line = malloc(sizeof(char) * (i + 2));
if (!line)
return (0);
j = 0;
while (j < i + 1)
{
line[j] = stash[j];
j++;
}
line[j] = '\0';
return (line);
}
Açıklama: Fonksiyon, stash içerisindeki veriden satır sonu karakterine
(\n) kadar olan kısmı kopyalayarak yeni bir string oluşturur. Bu şekilde, okunan satır
(satır sonu dahil) elde edilir. Eğer stash boşsa ya da bellek tahsisi başarısız olursa,
0 döner.
\n)
bulunup bulunmadığını kontrol eden yardımcı fonksiyondur.
static int ft_have_nl(char *s);s: Kontrol edilecek string.\n bulunursa
1, bulunmazsa 0 döner.
static int ft_have_nl(char *s)
{
size_t i;
if (!s)
return (0);
i = -1;
while (s[++i] != '\0')
if (s[i] == '\n')
return (1);
return (0);
}
Açıklama: Fonksiyon, verilen stringde satır sonu karakteri (\n) olup
olmadığını kontrol eder. Eğer satır sonu karakteri bulunursa 1, bulunmazsa 0
döner.
stash içerisine yeni okunan buf
verisini ekleyerek birleştirilmiş veriyi oluşturur.
static char *ft_copy_to_stash(char *stash, char *buf);
stash: Önceden okunan ve saklanan veriyi içeren string.buf: Yeni okunan veriyi içeren buffer.stash). Bellek
tahsisi hatası durumunda NULL döner.
static char *ft_copy_to_stash(char *stash, char *buf)
{
char *res;
res = 0;
if (!stash && buf)
{
res = ft_strdup(buf);
if (!res)
return (NULL);
return (res);
}
res = ft_strjoin(stash, buf);
ft_free_stash(&stash, 0);
return (res);
}
Açıklama: Fonksiyon, eğer stash boşsa doğrudan buf'u kopyalar;
aksi halde, mevcut stash ile buf verilerini birleştirir. Eski
stash belleği ft_free_stash fonksiyonu ile serbest bırakılır ve yeni
oluşturulan string döndürülür.
stash belleğini yönetmek için kullanılır. Eğer
create_line parametresi 0 ise, mevcut stash belleğini serbest bırakır ve
NULL döner; 1 ise stash içeriğini kopyalayıp belleği serbest bırakarak
kopyalanan stringi döndürür.
void *ft_free_stash(char **stash, int create_line);
stash: Bellek sızıntısını önlemek için serbest bırakılması gereken stringin
adresini tutan pointer.create_line: Belleğin serbest bırakılmadan önce kopyalanıp kopyalanmayacağını
belirleyen parametre; 0 ise serbest bırakılır, 1 ise kopyalanır ve kopya döndürülür.create_line 1 ise kopyalanan string, aksi
halde NULL döner.
void *ft_free_stash(char **stash, int create_line)
{
char *line;
if (!*stash)
return (NULL);
if (create_line == 0)
{
if (*stash)
{
free(*stash);
*stash = NULL;
}
return (NULL);
}
else if (create_line == 1)
{
line = ft_strdup(*stash);
free(*stash);
*stash = NULL;
return (line);
}
return (NULL);
}
Açıklama: Fonksiyon, stash belleğini uygun şekilde yönetir. Eğer
create_line 0 ise, mevcut stash serbest bırakılır ve NULL döner.
Eğer create_line 1 ise, stash içeriğinin bir kopyası oluşturulur,
orijinal stash belleği serbest bırakılır ve kopyalanan string döndürülür. Bu sayede bellek
sızıntısı önlenir.
ft_strlen: Dizinin uzunluğunu hesaplar.ft_strdup: Verilen stringin bir kopyasını döndürür.ft_strjoin: İki stringi birleştirip yeni bir string oluşturur.ft_substr: Belirli bir aralıktaki alt stringi döndürür.ft_free_stash: stash belleğini doğru şekilde yönetmek için
kullanılan fonksiyondur. Okuma tamamlandığında veya hatada NULL döndürerek
bellek sızıntısını engeller.
Buffer, dosyadan okuma yaparken verinin geçici olarak saklandığı alandır. get_next_line
fonksiyonu, read() sistem çağrısı ile BUFFER_SIZE kadar veri okuyup, bu veriyi
işlemek için buffer kullanır.
char buf[BUFFER_SIZE + 1];
bytes_read = read(fd, buf, BUFFER_SIZE);
Stash, okunan verilerin satır sonu karakterine (\n) kadar geçici olarak saklandığı dinamik
string'tir.
get_next_line fonksiyonu, okuma işlemleri arasında veriyi tutarak satırların eksiksiz bir
şekilde elde edilmesini sağlar.
static char *stash = NULL;
stash = ft_copy_to_stash(stash, buf);
Static değişkenler, fonksiyonlar arasında verinin korunmasını sağlayan, programın çalışma süresi boyunca
varlığını sürdüren değişkenlerdir.
get_next_line fonksiyonunda, stash static olarak tanımlanır; bu sayede
fonksiyon çağrıları arasında okunan veriler korunur.
Dinamik bellek tahsisi ve serbest bırakma, get_next_line fonksiyonunun doğru çalışması için
kritik öneme sahiptir.
Okunan satırlar ve stash verisi, bellek sızıntısını önlemek amacıyla uygun şekilde free
edilmelidir.
read() fonksiyonu, dosyadan veya standart girişten belirli sayıda byte okuyan bir sistem
çağrısıdır.
get_next_line fonksiyonu, bu sistem çağrısı ile veriyi okuyarak işlemeye başlar.
BUFFER_SIZE, get_next_line fonksiyonunun her okuma işleminde kullanacağı byte
miktarını belirleyen sabittir.
Bu değer, okuma performansı ve bellek kullanımı açısından önem taşır.
# ifndef BUFFER_SIZE
# define BUFFER_SIZE 5
# endif
Proje hakkında tüm görüş, öneri ve sorularınız için dilediğiniz zaman iletişime geçebilirsiniz.
daha çok yazı, bilgi ve içerik için takipte kalmayı unutmayın.
Projenin orijinal kaynak kodlarına aşağıdaki bağlantıdan ulaşabilirsiniz:
🔗 Proje GitHub Linki