- 1 1. Mis on fprintf funktsioon
- 2 2. fprintfi põhiline kasutamine
- 3 3. fprintfi vormingu kasutamine
- 4 4. Failihaldus ja fprintf
- 5 5. Vigade käsitlemine
- 6 6. Rakendusnäited
- 7 7. Korduma kippuvad küsimused (KKK)
- 8 8. Mitmesse faili samaaegne kirjutamine
- 9 9. Viitelinkid
1. Mis on fprintf funktsioon
fprintfi põhialused
fprintf
funktsioon on üks standardseid sisend-/väljundfunktsioone, mida kasutatakse C-keeles. Selle funktsiooni peamine roll on „väljastada vormindatud stringe”. fprintf
abil saab andmeid määratud vormingu järgi kujundada ja kirjutada määratud väljundisse.
Tavaliselt kasutatakse fprintf
-i järgmistes olukordades:
- Logifailide loomine: Programmi käivitamisajaloo või veateabe salvestamine.
- Vormindatud andmete salvestamine: Täisarvude või stringide salvestamine kindlas formaadis faili.
- Silumisinfo väljastamine: Arenduse ajal programmi töö jälgimiseks mõeldud andmete väljastamine.
fprintfi põhisüntaks
int fprintf(FILE *stream, const char *format, ...);
Süntaksi osad
FILE *stream
: Määrab väljundi sihtkoha. Näiteks standardväljund (stdout
) või fail (fopen
-iga avatud fail).const char *format
: Vormingustring, mis määrab, kuidas andmeid kuvatakse. Sama vorming naguprintf
-funktsioonis....
: Muutuv arv argumente, mis määravad väljundandmed.
Tagastusväärtus on edukalt kirjutatud märkide arv (positiivne täisarv). Kui ilmneb viga, tagastatakse -1
.
Võrdlus teiste funktsioonidega
fprintf
on sarnane funktsioonidega printf
ja sprintf
. Siin on nende erinevused:
Erinevus printfist
printf
väljastab andmed standardväljundisse (tavaliselt konsooli). fprintf
võimaldab määrata väljundi sihtkoha, pakkudes suuremat paindlikkust.
Näide: printf kasutamine
printf("Hello, World!\n");
Tulemus kuvatakse alati konsoolis.
Näide: fprintf kasutamine
FILE *file = fopen("output.txt", "w");
fprintf(file, "Hello, World!\n");
fclose(file);
Selles näites kirjutatakse väljund määratud faili (output.txt
).
Erinevus sprintfist
sprintf
erineb selle poolest, et väljundiks on „string” ehk mälus asuv puhver.
Näide: sprintf kasutamine
char buffer[50];
sprintf(buffer, "The result is %d", 42);
Selles näites kirjutatakse string "The result is 42"
muutujasse buffer
.
Kokkuvõte
fprintf
on kasulik funktsioon, mis võimaldab määrata väljundi sihtkoha (fail, standardväljund jne).- Kombineerides erinevaid funktsioone (
printf
,sprintf
) saab tõsta programmi efektiivsust ja loetavust.
2. fprintfi põhiline kasutamine
Süntaks ja põhiargumentide selgitus
fprintf
funktsioon on paindlik tööriist vormindatud andmete väljastamiseks. Selle põhisüntaks on järgmine:
int fprintf(FILE *stream, const char *format, ...);
Allpool on toodud argumentide üksikasjad.
- FILE *stream
- Määrab väljundi sihtkoha.
- Tüüpilised valikud:
- Standardväljund (
stdout
) - Standardne veaväljund (
stderr
) - Fail (
fopen
-iga avatud fail)
- Standardväljund (
- const char *format
- Määrab väljundi vormingu.
- Vorminguspetsiifereid saab kasutada stringide, täisarvude, ujukoma arvude jne jaoks (nt
%s
,%d
,%f
).
- Muutuva pikkusega argumendid (…)
- Annab andmed, mis vastavad vorminguspetsiiferitele.
- Näide: kui vorming on
"Name: %s, Age: %d"
, tuleb edasi anda vastavad väärtused nime ja vanuse jaoks.
Tagastusväärtus on edukalt kirjutatud märkide arv (positiivne täisarv). Kui ilmneb viga, tagastatakse -1
.
Põhilised koodinäited
Järgmised näited näitavad, kuidas fprintf
-i kasutada.
Väljund standardväljundisse
Kirjutab stringi vormindatult standardväljundisse (stdout
).
#include <stdio.h>
int main() {
fprintf(stdout, "Hello, %s! You have %d new messages.\n", "Alice", 5);
return 0;
}
Väljund:
Hello, Alice! You have 5 new messages.
Selles näites on stdout
selgesõnaliselt määratud väljundiks.
Väljund faili
fprintf
abil saab kirjutada andmeid faili.
#include <stdio.h>
int main() {
FILE *file = fopen("output.txt", "w"); // Avab faili kirjutamisrežiimis
if (file == NULL) {
fprintf(stderr, "Error opening file.\n");
return 1;
}
fprintf(file, "Name: %s, Age: %d\n", "Bob", 30);
fclose(file); // Sulgeb faili
return 0;
}
output.txt sisu:
Name: Bob, Age: 30
Põhilised vorminguspetsiiferid
fprintf
võimaldab kontrollida väljundi kuju vorminguspetsiiferite abil. Allpool on toodud mõned põhilised näited.
Spetsiifer | Selgitus | Näide |
---|---|---|
%d | Kümnendsüsteemi täisarv | 42 |
%f | Ujukoma arv | 3.141593 |
%s | String | "Hello" |
%c | Üksik märk | 'A' |
%x | Kuueteistkümnendsüsteemi arv (väiketähed) | 0x2a |
%o | Kaheksandsüsteemi arv | 052 |
Näide:
fprintf(stdout, "Integer: %d, Float: %.2f, String: %s\n", 10, 3.14, "Test");
Väljund:
Integer: 10, Float: 3.14, String: Test
3. fprintfi vormingu kasutamine
Laius (Minimum Width)
Kui määrata välja laiuse, täidetakse vasakpoolne ruum tühikutega, kui väljastatava stringi pikkus jääb alla määratud laiuse.
Näide:
fprintf(stdout, "|%10s|\n", "Hello");
fprintf(stdout, "|%10d|\n", 123);
Väljund:
| Hello|
| 123|
Siin on laiuseks määratud 10. Kui sümbolite arv on väiksem, lisatakse vasakule poole tühikud.
Täpsus (Precision)
Täpsusel on erinev tähendus sõltuvalt kasutusviisist:
- Stringid (%s): maksimaalne väljastatavate märkide arv.
- Ujukoma arvud (%f, %e, %g): komakohtade arv pärast koma.
Näide:
fprintf(stdout, "%.3f\n", 3.141592); // Ujukoma täpsus
fprintf(stdout, "%.5s\n", "Hello, World!"); // Stringi maksimaalne pikkus
Väljund:
3.142
Hello
Lipud (Flags)
Lippude abil saab kontrollida andmete paigutust ja vormingut.
Lipp | Selgitus | Näide |
---|---|---|
- | Joondamine vasakule (vaikimisi paremale) | |%-10s| → |Hello | |
+ | Märgi kuvamine alati (ka positiivse arvu korral) | %+d → +42 |
0 | Täidab tühikud nullidega (kasutatakse laiuse määramisel) | %05d → 00042 |
# | Lisa eri vorming (16-nd või 8-nd süsteem) | %#x → 0x2a |
Lisab positiivse arvu ette tühiku | % d → 42 |
Näide:
fprintf(stdout, "|%-10s|%+05d|%#x|\n", "Left", 42, 42);
Väljund:
|Left |+0042|0x2a|
Praktilised näited
Kombineerides laiust, täpsust ja lippe, saab fprintf
-i abil luua hästi vormindatud tabeli kujulisi andmeid.
Tabelina väljastamine
Järgmises näites väljastatakse õpilaste hinded tabelina:
#include <stdio.h>
int main() {
fprintf(stdout, "|%-10s|%5s|%5s|%5s|\n", "Name", "Math", "Eng", "Sci");
fprintf(stdout, "|%-10s|%5d|%5d|%5d|\n", "Alice", 95, 88, 92);
fprintf(stdout, "|%-10s|%5d|%5d|%5d|\n", "Bob", 82, 79, 85);
return 0;
}
Väljund:
|Name | Math| Eng| Sci|
|Alice | 95| 88| 92|
|Bob | 82| 79| 85|
Arvude vormindamine
Kindla formaadiga arvude väljastamine ühtse välimuse saavutamiseks.
Näide:
fprintf(stdout, "Price: $%8.2f\n", 1234.5);
fprintf(stdout, "Discount: %06d%%\n", 25);
Väljund:
Price: $ 1234.50
Discount: 000025%
Olulised märkused
- Vale vorminguspetsiifer
- Kui vorminguspetsiifer ei sobi andmetüübi juurde, võib tekkida ootamatu väljund või viga.
- Näide: stringi edastamine
%d
jaoks võib põhjustada määramata käitumise.
- Laiuse ja täpsuse liigne määramine
- Kui määrata liiga suur laius, võib väljund muutuda liiga pikaks ja raisata ressursse.
Kokkuvõte
- Laiuse, täpsuse ja lippude abil saab
fprintf
-i väljundit täpselt kontrollida. - Tabeliandmete ja arvude vormindamine muudab väljundi loetavamaks.
- Oluline on tagada, et vorminguspetsiiferid ja andmetüübid vastaksid, et vältida vigu.
4. Failihaldus ja fprintf
Faili avamine (fopen)
Selleks, et fprintf
abil faili kirjutada, tuleb fail esmalt avada. C-keeles kasutatakse selleks fopen
funktsiooni.
fopeni põhisüntaks
FILE *fopen(const char *filename, const char *mode);
Argumentide selgitus
filename
: avatava faili nimi või tee.mode
: määrab, kuidas faili avatakse."r"
: ainult lugemiseks"w"
: ainult kirjutamiseks (olemasolev fail kirjutatakse üle)"a"
: lisamine (kirjutatakse faili lõppu)"rb"
/"wb"
/"ab"
: sama, kuid binaarrežiimis
Tagastusväärtus
- Kui avamine õnnestub, tagastatakse
FILE
tüüpi pointer. - Kui avamine ebaõnnestub, tagastatakse
NULL
.
fopeni näide
#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
fprintf(file, "Hello, World!\n");
fclose(file);
return 0;
}
See programm avab faili example.txt
, kirjutab sinna teksti ja sulgeb faili.
Faili kirjutamine fprintf abil
fprintf
võimaldab kirjutada vormindatud andmeid faili. Siin on mõned näited.
Põhiline faili kirjutamine
#include <stdio.h>
int main() {
FILE *file = fopen("data.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
fprintf(file, "Name: %s, Age: %d\n", "Alice", 25);
fprintf(file, "Name: %s, Age: %d\n", "Bob", 30);
fclose(file);
return 0;
}
data.txt sisu:
Name: Alice, Age: 25
Name: Bob, Age: 30
CSV-faili loomine
Näide CSV-andmete salvestamisest:
#include <stdio.h>
int main() {
FILE *file = fopen("students.csv", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
// Päis
fprintf(file, "Name,Math,English,Science\n");
// Andmed
fprintf(file, "Alice,95,88,92\n");
fprintf(file, "Bob,82,79,85\n");
fclose(file);
return 0;
}
students.csv sisu:
Name,Math,English,Science
Alice,95,88,92
Bob,82,79,85
Faili sulgemine (fclose)
Pärast faili kasutamist tuleb see sulgeda fclose
funktsiooni abil. Kui faili ei suleta, võivad tekkida probleemid:
- Andmeid ei pruugita täielikult salvestada.
- Süsteemi ressursse kulutatakse asjatult.
fclose põhisüntaks
int fclose(FILE *stream);
Tagastusväärtus
- Edu korral
0
. - Tõrke korral
EOF
(faili lõpu märgis).
fclose näide
FILE *file = fopen("example.txt", "w");
if (file != NULL) {
fprintf(file, "This is a test.\n");
fclose(file);
}
Turvalise failihalduse soovitused
- Kontrolli faili pointerit
- Kontrolli alati, kas
fopen
tagastasNULL
.
- Ära unusta faili sulgeda
- Iga avatud fail tuleb sulgeda
fclose
abil.
- Veaohje
- Tuvasta ja käsitle vigu failitoimingute käigus.
- Näiteks: kettaruumi puudus või õiguste probleemid.
Kokkuvõte
- Fail tuleb avada
fopen
-iga ja sulgedafclose
-iga. - Õige režiimi ja vigade kontroll tagavad turvalise failihalduse.
fprintf
abil saab salvestada CSV-formaadis või logisid.
5. Vigade käsitlemine
fprintfi tagastusväärtuse kasutamine vigade kontrolliks
Kontrollides fprintf
funktsiooni tagastusväärtust saab tuvastada, kas kirjutamine õnnestus või mitte.
Tagastusväärtuse spetsifikatsioon
- Eduka kirjutamise korral: tagastatakse kirjutatud märkide arv (positiivne täisarv).
- Vea korral: tagastatakse
-1
.
Põhiline vea kontrolli näide
#include <stdio.h>
int main() {
FILE *file = fopen("output.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
int result = fprintf(file, "Hello, World!\n");
if (result < 0) {
fprintf(stderr, "Error: Failed to write to file.\n");
}
fclose(file);
return 0;
}
Selles programmis kontrollitakse fprintf
tagastusväärtust ning vea korral väljastatakse teade.
Standardne veaväljund (stderr)
stderr
on standardne voog, mida kasutatakse vigade ja hoiatuste väljastamiseks. Väljastades veateated stderr
-i kaudu, saab need eristada tavalisest väljundist (stdout
).
Näide: stderr kasutamine
#include <stdio.h>
int main() {
FILE *file = fopen("nonexistent_dir/output.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Unable to open file. Check the directory path.\n");
return 1;
}
fclose(file);
return 0;
}
Väljund (vea korral):
Error: Unable to open file. Check the directory path.
Kasutades stderr
-i, saab veateated eraldada tavalisest väljundist.
Praktiline veakäsitluse näide
Allpool on toodud failikirjutamise tüüpiline veakäsitluse kood.
Näide: kirjutamise ja sulgemise veakontroll
#include <stdio.h>
int main() {
FILE *file = fopen("output.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
// Kirjutamise kontroll
if (fprintf(file, "Logging data: %d\n", 42) < 0) {
fprintf(stderr, "Error: Failed to write to file.\n");
fclose(file);
return 1;
}
// Faili sulgemise kontroll
if (fclose(file) != 0) {
fprintf(stderr, "Error: Failed to close the file.\n");
return 1;
}
printf("File operation completed successfully.\n");
return 0;
}
Põhipunktid:
- Kontrollitakse igat sammu: avamine, kirjutamine ja sulgemine.
- Vea korral väljastatakse sobiv teade ja programm lõpetatakse.
Levinud vead ja lahendused
1. Faili ei saa avada
Põhjused:
- Faili pole olemas.
- Kataloogitee on vale.
- Õigused puuduvad.
Lahendused:
- Kontrolli failiteed.
- Paranda faililubasid.
- Kontrolli
fopen
tagastusväärtust.
2. Kirjutamine ebaõnnestub
Põhjused:
- Kettaruumi puudus.
- Fail avati ainult lugemiseks.
Lahendused:
- Kontrolli avamisrežiimi (
"w"
,"a"
). - Kontrolli kettaruumi.
3. Faili sulgemise viga
Põhjused:
- Süsteemi ressursipuudus.
- Riistvaraprobleem.
Lahendused:
- Kontrolli sulgemisel tagastusväärtust.
- Kasuta minimaalselt vajalikke ressursse.
Kokkuvõte
- Kontrollides
fprintf
tagastusväärtust saab tuvastada kirjutamisvead. - Kasutades
stderr
-i saab veateated selgelt eristada tavalisest väljundist. - Põhjalik vigade käsitlus failitoimingute igas etapis parandab programmi töökindlust.
6. Rakendusnäited
Logifailide automaatne loomine
Logifaile kasutatakse programmi töö oleku ja vigade salvestamiseks. Allpool on näide logimisest koos kuupäeva ja kellaajaga.
Näide: ajatempli lisamine logisse
#include <stdio.h>
#include <time.h>
int main() {
FILE *logFile = fopen("log.txt", "a"); // Avamine lisamisrežiimis
if (logFile == NULL) {
fprintf(stderr, "Error: Could not open log file.\n");
return 1;
}
time_t now = time(NULL);
struct tm *localTime = localtime(&now);
fprintf(logFile, "[%04d-%02d-%02d %02d:%02d:%02d] Program started\n",
localTime->tm_year + 1900, localTime->tm_mon + 1, localTime->tm_mday,
localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
fclose(logFile);
return 0;
}
log.txt sisu:
[2025-01-19 15:45:30] Program started
Põhipunktid
- Kasutatakse
time.h
teegi funktsioone, et saada praegune aeg. - Avamisrežiim
"a"
tagab, et andmed lisatakse faili lõppu.
Tabeli kujul andmete kirjutamine
Andmete väljastamine tabelina on kasulik näiteks raportite või aruannete jaoks.
Näide: õpilaste hinded
#include <stdio.h>
int main() {
FILE *file = fopen("report.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
fprintf(file, "|%-10s|%6s|%6s|%6s|\n", "Name", "Math", "Eng", "Sci");
fprintf(file, "|%-10s|%6d|%6d|%6d|\n", "Alice", 90, 85, 88);
fprintf(file, "|%-10s|%6d|%6d|%6d|\n", "Bob", 78, 82, 80);
fclose(file);
return 0;
}
report.txt sisu:
|Name | Math| Eng| Sci|
|Alice | 90| 85| 88|
|Bob | 78| 82| 80|
Põhipunktid
- Vasak- ja parempoolne joondus (
%-10s
,%6d
) teevad väljundi loetavaks.
Andmete salvestamine CSV-vormingus
CSV (Comma-Separated Values) on kasulik andmete vahetamiseks teiste rakendustega.
Näide: CSV faili kirjutamine
#include <stdio.h>
int main() {
FILE *file = fopen("data.csv", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
// Päis
fprintf(file, "Name,Math,English,Science\n");
// Andmeread
fprintf(file, "Alice,90,85,88\n");
fprintf(file, "Bob,78,82,80\n");
fclose(file);
return 0;
}
data.csv sisu:
Name,Math,English,Science
Alice,90,85,88
Bob,78,82,80
Põhipunktid
- Väljade eraldamiseks kasutatakse koma (
,
), mis sobib Exceli või Pythoniga töötlemiseks.
Silumisinfo salvestamine
Silumislogid võimaldavad jälgida programmi tööseisundit.
Näide: muutuja logimine
#include <stdio.h>
int main() {
FILE *debugFile = fopen("debug.log", "w");
if (debugFile == NULL) {
fprintf(stderr, "Error: Could not open debug log file.\n");
return 1;
}
int x = 42;
fprintf(debugFile, "Debug: Variable x = %d\n", x);
fclose(debugFile);
return 0;
}
debug.log sisu:
Debug: Variable x = 42
Põhipunktid
- Silumisinfo failis aitab vigu kiiremini tuvastada.
Kokkuvõte
fprintf
sobib logide, tabeliandmete ja CSV-de loomiseks.- Tööpraktikas on eriti kasulikud kuupäevaga logid ja CSV-formaadis failid.
- Rakendusnäited aitavad paremini mõista
fprintf
-i praktilist kasutust.
7. Korduma kippuvad küsimused (KKK)
1. Mis vahe on fprintfil ja printfil?
Vastus
printf
:- Väljastab andmed standardväljundisse (tavaliselt konsooli).
- Väljundkohta muuta ei saa.
fprintf
:- Võimaldab valida väljundi sihtkoha (nt fail, standardväljund, veaväljund).
- Paindlikum andmete väljastamiseks.
Näide
#include <stdio.h>
int main() {
printf("This is printed to the console.\n"); // alati konsooli
FILE *file = fopen("output.txt", "w");
if (file != NULL) {
fprintf(file, "This is written to a file.\n"); // faili kirjutamine
fclose(file);
}
return 0;
}
2. Kuidas fprintf abil õigesti jaapani keelt (või teisi UTF-8 märke) väljastada?
Vastus
- Õigete märkide väljastamiseks tuleb tähelepanu pöörata järgmistele punktidele:
- Kooditabel:
- Kasuta keskkonnale sobivat kodeeringut (nt UTF-8, Shift-JIS).
- Faili kodeering:
- Kirjutatav fail peab kasutama sama kodeeringut, mis keskkond.
Näide: UTF-8 kasutamine
#include <stdio.h>
#include <locale.h>
int main() {
setlocale(LC_ALL, ""); // seadista lokaadid
FILE *file = fopen("japanese.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
fprintf(file, "こんにちは、世界!\n");
fclose(file);
return 0;
}
Märkus:
- Mõnes keskkonnas tuleb vältida tähemärkide moondumist, määrates kodeering selgesõnaliselt.
3. Mis põhjustab fprintfi tõrkeid?
Vastus
- Levinumad põhjused on järgmised:
- Faili ei saa avada:
- Vale failitee.
- Puuduvad õigused.
- Kettaruumi puudus:
- Kirjutamise ajal pole piisavalt ruumi.
- Vale vorminguspetsiifer:
- Andmetüüp ei ühti vorminguspetsiiferiga.
Näide: vorminguspetsiiferi sobimatus
#include <stdio.h>
int main() {
FILE *file = fopen("error.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
// Siin kasutatakse %s, kuid antakse täisarv → määramata käitumine
fprintf(file, "%s", 42);
fclose(file);
return 0;
}
Lahendus:
- Kontrolli, et vorming ja andmetüüp kattuvad (nt
%d
täisarvude jaoks,%s
stringide jaoks).
4. Mis mõju on puhverdamisel (buffering)?
Vastus
- Puhverdamine:
- Andmed kirjutatakse esmalt puhvrisse ja alles seejärel faili.
- Probleem:
- Kui programm katkeb ootamatult, võivad puhvrisse jäänud andmed kaduma minna.
Lahendus
- Kasutada
fflush
:- Puhvri tühjendamiseks ja andmete koheseks kirjutamiseks.
Näide: fflush kasutamine
#include <stdio.h>
int main() {
FILE *file = fopen("buffered_output.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
fprintf(file, "Buffered data.\n");
fflush(file); // sunnib kohe kirjutama
fclose(file);
return 0;
}
5. Mida teha, kui faili väljund katkeb pooleli?
Vastus
- Põhjused võivad olla järgmised:
- Faili ei suleta:
- Puhvrit ei tühjendata ja osa andmeid kaob.
- Kettaruumi puudus:
- Kirjutamine katkeb, kui kettaruumi napib.
Näide: faili sulgemine
#include <stdio.h>
int main() {
FILE *file = fopen("partial_output.txt", "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open file.\n");
return 1;
}
fprintf(file, "This is complete data.\n");
// Ära unusta faili sulgeda
fclose(file);
return 0;
}
Lahendus:
- Kasuta alati
fclose
, et lõpetada kirjutamine korrektselt. - Kontrolli tagastusväärtusi võimalike vigade tuvastamiseks.
Kokkuvõte
fprintf
on paindlik funktsioon, kuid korrektne veakäsitlus ja kodeering on hädavajalikud.- KKK annab ülevaate sagedastest probleemidest ja nende lahendustest.
8. Mitmesse faili samaaegne kirjutamine
Kasutades fprintf
-i, on võimalik kirjutada andmeid korraga mitmesse faili. Selles osas vaatleme praktilisi meetodeid samaaegseks faili väljundiks.
Mitme faili haldamise põhiidee
C keeles saab avada mitu FILE
pointerit ja hallata neid eraldi. Oluline on igale failile rakendada fopen
, fprintf
ja fclose
.
Näide: kahe faili samaaegne kirjutamine
#include <stdio.h>
int main() {
// Ava kaks faili
FILE *file1 = fopen("output1.txt", "w");
FILE *file2 = fopen("output2.txt", "w");
if (file1 == NULL || file2 == NULL) {
fprintf(stderr, "Error: Could not open one of the files.\n");
if (file1) fclose(file1);
if (file2) fclose(file2);
return 1;
}
// Kirjuta faili 1
fprintf(file1, "This is the first file.\n");
// Kirjuta faili 2
fprintf(file2, "This is the second file.\n");
// Sulge failid
fclose(file1);
fclose(file2);
printf("Data written to both files successfully.\n");
return 0;
}
output1.txt sisu:
This is the first file.
output2.txt sisu:
This is the second file.
Põhipunktid
- Vea kontroll: kontrolli alati, kas
fopen
õnnestus. - Ressursside vabastamine: sulge alati kõik avatud failid
fclose
-iga.
Dünaamiline failihaldus
Dünaamiliselt failinimesid genereerides saab korraga kirjutada mitmesse faili tsüklis.
Näide: dünaamilised failinimed
#include <stdio.h>
int main() {
char filename[20];
for (int i = 1; i <= 3; i++) {
sprintf(filename, "file%d.txt", i);
FILE *file = fopen(filename, "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open %s\n", filename);
continue;
}
fprintf(file, "This is file number %d\n", i);
fclose(file);
}
printf("Data written to files successfully.\n");
return 0;
}
Loodud failid:
file1.txt
:This is file number 1
file2.txt
:This is file number 2
file3.txt
:This is file number 3
Põhipunktid
- Kasutatakse
sprintf
-i failinime loomiseks tsüklis. - Kui fail ei avane, liigutakse järgmise juurde.
Paralleelne kirjutamine
Suuremahulise samaaegse kirjutamise jaoks võib kasutada lõime (threads).
Näide: POSIX pthread abil paralleelne kirjutamine
#include <stdio.h>
#include <pthread.h>
void *write_to_file(void *arg) {
char *filename = (char *)arg;
FILE *file = fopen(filename, "w");
if (file == NULL) {
fprintf(stderr, "Error: Could not open %s\n", filename);
return NULL;
}
fprintf(file, "Data written to %s\n", filename);
fclose(file);
return NULL;
}
int main() {
pthread_t threads[3];
char *filenames[] = {"thread1.txt", "thread2.txt", "thread3.txt"};
for (int i = 0; i < 3; i++) {
pthread_create(&threads[i], NULL, write_to_file, filenames[i]);
}
for (int i = 0; i < 3; i++) {
pthread_join(threads[i], NULL);
}
printf("Data written to all files in parallel.\n");
return 0;
}
Loodud failid:
thread1.txt
:Data written to thread1.txt
thread2.txt
:Data written to thread2.txt
thread3.txt
:Data written to thread3.txt
Põhipunktid
- Lõimede abil saab kirjutada paralleelselt mitmesse faili.
- Oluline on kasutada
pthread_join
-i, et oodata lõimede lõppemist.
Kokkuvõte
fprintf
abil saab samaaegselt kirjutada mitmesse faili.- Dünaamilised failinimed ja paralleelne töötlus suurendavad paindlikkust ja jõudlust.
- Oluline on vabastada ressursid (
fclose
) ja käsitleda vigu.
9. Viitelinkid