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
#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
#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
FILE *f = fopen(____, "w");
FILE *f = fopen(path, "w");
Açıklama: fopen(path, "w") dosyayı yazma modunda açar.