ungetc()

Kategori: C , 30 Haziran 2019 , JanFranco


getc fonksiyonunun aksine, ungetc fonksiyonu, dosya akışından aldığı bir karakteri, akışa geri koyar. Böylece o karaktere tekrar erişebiliriz. Örneğe geçmeden önce fonksiyon prototipini verelim:


int ungetc(int c, FILE *stream);
İlk parametre olarak karakteri, ikinci parametre olarak dosya akışını alır. Dosya akışından kasıt file pointer'dır. Bir örnek üzerinden olayı ve mantığı gösterelim:

#include <stdio.h>

char read_punctstring(FILE *fp, char *s){

    char origpunct, c;

    origpunct = fgetc(fp);

    if (origpunct == EOF)
        return EOF;

    while(c = fgetc(fp), !ispunct(c) && c != EOF) {
        *s++ = c;
    }

    *s = '\0';

    ungetc(c, fp);

    return origpunct;
}
Bu fonksiyonda öncelikle origpunct ve c isimlerinde iki char değişkeni tanımladık. Daha sonra dosyadan aldığığımız ilk karakteri origpunct değişkeninde sakladık. Eğer origpunct değişkeni EOF ise fonksiyonu sonlandırdık. while döngüsü ile, bir punct'a denk gelene kadar ve dosyanın sonuna kadar tüm karakterleri okuyup c'ye atadık. Her bir iteration'da okuduğumuz c karakterini, parametre olarak gönderdiğimiz s stringine ekledik. Döngüden çıktığımızda s stringin sonuna bir sonlandırıcı olan \0 karakterini ekledik. Daha sonra son okudğumuz karakteri, akışa geri dahil ettik ve ilk okuduğumuz karakteri return ettik. main fonksiyonunu açıklamadan önce bu fonksiyonun nasıl çalışacağından, davranış göstereceğinden bahsedelim. Parametre olarak gönderdiğimiz dosyanın içeriği aşağıdaki gibi olsun:

!foo#bar*baz
origpunct değişkeninde '!' karakteri saklanacak, s striginde de 'foo' karakterleri saklanacak. Bu arada bahsetmediğimiz bir şey var. ispunct() fonksiyonu bir karakterin punctuation karakteri olup olmadığını kontrol eder. Tüm punctuation karakterleri aşağıdadır:

! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
s stringde '!foo' karakterleri yerine 'foo' karakterlerinin saklanmasının sebebi, s strigine karakter ataması yapacakken punctation karakteri olup olmadığını kontrol etmemizdir. s stringini tamamladık ancak burada bir sıkıntı vardır. Şuanda file pointer # karakterini atladı ve b karakterine geçti. while döngüsünde f, o, o karakterlerini aldıktan sonra # karakteri geldi ve while döngüsü, bu karakter bir punctation karakter olduğundan sonlandı. Ve # karakteri atlandığında file pointer b karakterini göstermeye başladı. Bu fonksiyonda eğer ungetc fonksiyonunu kullanmasaydık, fonksiyon bir kez daha çağırıldığında b karakterinden okumaya başlayacaktı. Bunu engellemek için ungetc fonksiyonu ile # karakterini akışa dahil ettik. Şimdi bu fonksiyonu 3 kez ard arda çağıralım:

int main() {

    FILE *fp = fopen("myFile.txt", "r");

    char c;
    char *s = malloc(sizeof(char)*100);

    c = read_punctstring(fp, s);

    printf("c: %c\n", c);
    printf("s: %s\n", s);

    c = read_punctstring(fp, s);

    printf("c: %c\n", c);
    printf("s: %s\n", s);

    c = read_punctstring(fp, s);

    printf("c: %c\n", c);
    printf("s: %s\n", s);
    
    return 0;
}
>>

c: !
s: foo
c: #
s: bar
c: *
s: baz


Sonraki Yazı: fread(), fwrite()
Yorumlar

Henüz bir yorum bulunmuyor.
Yorum bırakın