CodeBlanks Logo Icon CodeBlanks

Dosya I/O

  • C kursu
  • Orta seviye
  • Ders 115/116
  • 6 dk

Verileri dosyaya kaydedip yüklersin.

Görevleri kaydetme

Dördüncü ders, görevleri dosyaya kaydetme ve dosyadan yükleme fonksiyonlarını ekler. task_save, bağlı listeyi bir metin dosyasına yazar; task_load, dosyayı okuyup listeyi yeniden kurar.

task_save, fopen ile dosyayı yazma modunda açar, fprintf ile her görevin adını ve önceliğini yazar, fclose ile kapatır. task_load, fscanf ile ad ve önceliği okur, task_new ile görev oluşturup task_push_front ile listeye ekler. Bu, kalıcı depolamanın temelidir; program kapansa bile veriler dosyada kalır. Önceki dersin kodu bu dersin başlangıç koduna dahildir.

Kaydet ve yükle

Kaydetme ve yükleme işlemleri birlikte çalışır. Kaydetme listedeki her görevi dosyaya yazar; yükleme dosyadan okuyup listeyi yeniden kurar. Arada listeyi serbest bırakarak temiz bir başlangıç yaparsın.

Akış: task_save(g_list, "tasks.txt"); ile kaydedersin. Listeyi serbest bırakıp g_list = NULL; yaparsın. Sonra task_load(&g_list, "tasks.txt"); ile yeniden yüklersin. Yükleme, task_push_front kullandığı için sıra tersine döner; bu, bağlı listenin doğal davranışıdır. Bu test, kaydetme ve yükleme işlemlerinin birbirine uygun olduğunu doğrular; ne kaydettiysen onu geri alırsın.

Uygulama Kaydet ve yükle ekle

int task_save(const Task *list, const char *path) yaz; fopen(path, "w") ile aç, fprintf(f, "%s %d\n", ...) ile yaz, fclose(f) ile kapat. int task_load(Task **list, const char *path) yaz; fopen(path, "r") ile aç, fscanf(f, "%31s %d", ...) ile oku, task_push_front ile ekle. main içinde iki görev ekle, task_save(g_list, "tasks.txt"); çağır, listeyi serbest bırak, task_load(&g_list, "tasks.txt"); çağır, yüksek sayısını yazdır.

Başlangıç kodu

main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Task {
    char name[32];
    int priority;
    struct Task *next;
} Task;

Task *g_list = NULL;

Task *task_new(const char *name, int priority) {
    Task *t = malloc(sizeof(Task));
    strncpy(t->name, name, 31);
    t->name[31] = '\0';
    t->priority = priority;
    t->next = NULL;
    return t;
}

void task_push_front(Task **list, Task *t) {
    t->next = *list;
    *list = t;
}

void task_print(const Task *list) {
    const Task *cur = list;
    while (cur) {
        printf("%s: %d\n", cur->name, cur->priority);
        cur = cur->next;
    }
}

typedef int (*TaskFilter)(const Task *);

int is_high_priority(const Task *t) {
    return t->priority >= 3;
}

int task_count_if(const Task *list, TaskFilter filter) {
    int count = 0;
    const Task *cur = list;
    while (cur) {
        if (filter(cur)) count++;
        cur = cur->next;
    }
    return count;
}

// task_save fonksiyonunu yaz
// task_load fonksiyonunu yaz
// main'de kaydet, serbest bırak, yükle ve yazdır

int main(void) {
    task_push_front(&g_list, task_new("Ödeme", 1));
    task_push_front(&g_list, task_new("Paketle", 3));
    task_print(g_list);
    int high = task_count_if(g_list, is_high_priority);
    printf("yüksek: %d\n", high);
    return 0;
}

Örnek çözüm

main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Task {
    char name[32];
    int priority;
    struct Task *next;
} Task;

Task *g_list = NULL;

Task *task_new(const char *name, int priority) {
    Task *t = malloc(sizeof(Task));
    strncpy(t->name, name, 31);
    t->name[31] = '\0';
    t->priority = priority;
    t->next = NULL;
    return t;
}

void task_push_front(Task **list, Task *t) {
    t->next = *list;
    *list = t;
}

void task_print(const Task *list) {
    const Task *cur = list;
    while (cur) {
        printf("%s: %d\n", cur->name, cur->priority);
        cur = cur->next;
    }
}

typedef int (*TaskFilter)(const Task *);

int is_high_priority(const Task *t) {
    return t->priority >= 3;
}

int task_count_if(const Task *list, TaskFilter filter) {
    int count = 0;
    const Task *cur = list;
    while (cur) {
        if (filter(cur)) count++;
        cur = cur->next;
    }
    return count;
}

int task_save(const Task *list, const char *path) {
    FILE *f = fopen(path, "w");
    if (!f) return 0;
    const Task *cur = list;
    while (cur) {
        fprintf(f, "%s %d\n", cur->name, cur->priority);
        cur = cur->next;
    }
    fclose(f);
    return 1;
}

int task_load(Task **list, const char *path) {
    FILE *f = fopen(path, "r");
    if (!f) return 0;
    char name[32];
    int priority;
    while (fscanf(f, "%31s %d", name, &priority) == 2) {
        task_push_front(list, task_new(name, priority));
    }
    fclose(f);
    return 1;
}

int main(void) {
    task_push_front(&g_list, task_new("Ödeme", 1));
    task_push_front(&g_list, task_new("Paketle", 3));
    task_save(g_list, "tasks.txt");
    Task *cur = g_list;
    while (cur) { Task *n = cur->next; free(cur); cur = n; }
    g_list = NULL;
    task_load(&g_list, "tasks.txt");
    int high = task_count_if(g_list, is_high_priority);
    printf("yüksek: %d\n", high);
    return 0;
}

Beklenen çıktı

yüksek: 1

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 task_save hangi fonksiyonla dosyaya yazar?

  • malloc
  • printf
  • scanf
  • fprintf Doğru cevap

Açıklama: fprintf bir dosya akışına biçimli çıktı yazar.

2 Dosya I/O fonksiyonlarını eşle

Kavram Anlamı
fopen Dosya aç
fprintf Dosyaya yaz
fscanf Dosyadan oku
fclose Dosya kapat

3 fopen çağrısını tamamla

Soru
FILE *f = fopen(____, "w");
Cevap
FILE *f = fopen(path, "w");

Açıklama: fopen(path, "w") dosyayı yazma modunda açar.

Orta seviye bölümündeki tüm dersler