Académique Documents
Professionnel Documents
Culture Documents
Xuáút nháûp file (File I/O) laì mäüt trong nhæîng khêa caûnh phæïc taûp nháút cuía báút kyì
ngän ngæî láûp trçnh naìo båíi vç noï gàõn boï máût thiãút våïi hãû âiãöu haình. Caïc hãû âiãöu
haình biãún âäøi nhiãöu daûng khaïc nhau âãø cho pheïp truy cáûp dæî liãûu trong caïc file
vaì caïc thiãút bë. Caïc sæû thay âäøi naìy taûo cho ta caïc khoï khàn âãø thiãút kãú caïc khaí
nàng xuáút/nháûp (I/O) maì coï tênh khaí chuyãøn tæì mäüt caìi âàût cuía mäüt ngän ngæî
láûp trçnh naìy sang mäüt ngän ngæî láûp trçnh khaïc.
Ngän ngæî C biãøu diãùn I/O thäng qua mäüt táûp ráút nhiãöu caïc haìm chuáøn. Nhiãöu
trong säú nhæîng haìm naìy âaî âæåüc mä taí láön âáöu tiãn trong chuáøn K&R. Mäüt säú
khaïc âæåüc ruït ra tæì thæ viãûn I/O cuía UNIX.
UÍy ban ANSI âaî kãút näúi 2 thæ viãûn naìy laûi, phaït triãøn mäüt säú haìm, loaûi boí âi
mäüt säú, vaì sæía âäøi nhæîng caïi coìn laûi. Trong thæ viãûn ANSI, táút caí caïc haìm I/O
âãöu phaíi sæí duûng bäü âãûm, ta cuîng coï khaí nàng thay âäøi kêch cåî bäü âãûm naìy.
Thãm vaìo âoï, caïc haìm I/O cuía ANSI taûo ra mäüt sæû khaïc biãût giæîa caïch truy cáûp
file åí chãú âäü nhë phán vaì åí chãú âäü vàn baín.
Thæ viãûn chuáøn cuía C chæïa gáön 40 haìm biãøu diãùn caïc pheïp toaïn I/O. Chuïng coï
thãø âæåüc chia thaình nhiãöu nhoïm.
Âãø biãøu diãùn caïc pheïp toaïn I/O, ta phaíi näúi kãút mäüt stream våïi mäüt haìm hay
mäüt thiãút bë. Ta coï thãø laìm âiãöu naìy bàòng caïch khai baïo mäüt con troí troí âãún mäüt
kiãøu cáúu truïc goüi laì FILE. Cáúu truïc FILE, âæåüc âënh nghéa åí stdio.h, chæïa mäüt
säú træåìng âãø læu caïc thäng tin nhæ tãn file, chãú âäü truy cáûp cuía noï, vaì mäüt con
troí troí âãún kyï tæû tiãúp theo trong stream. Caïc træåìng naìy seî âæåüc nháûn giaï trë khi
ta måí stream vaì truy cáûp âãún noï.
Cáúu truïc FILE cung cáúp cho hãû âiãöu haình thäng tin våïi caïc thäng tin giæî chäù,
nhæng ta chè coï thãø truy cáûp stream thäng qua mäüt phæång tiãûn âoï laì con troí troí
âãún cáúu truïc FILE, goüi laì con troí file. Con troí file læu giæî biãún stream âæåüc traí
vãö tæì haìm fopen(). Ta duìng con troí file âãø âoüc, ghi dæî liãûu hoàûc âoïng stream.
Mäüt chæång trçnh coï thãø coï nhiãöu hån mäüt stream måí âäöng thåìi, do duì mäùi caìi
âàût âãöu chè cho pheïp mäüt säú giåïi haûn caïc stream âæåüc måí.
Mäüt trong nhæîng træåìng cuía cáúu truïc FILE laì bäü âënh vë file (file position
indicator) noï chè âãún byte maì åí âoï kyï tæû kãú tiãúp seî âæåüc âoüc hoàûc ghi. Khi ta
âoüc vaì ghi file, hãû âiãöu haình âënh vë bäü chè vë trê file âãún con troí troí âãún byte
tiãúp theo. Traïnh nháöm láùn giæîa con troí file vaì bäü âënh vë file. Con troí file xaïc
âënh mäúi liãn kãút giæîa mäüt stream âaî måí våïi mäüt file hay thiãút bë. Bäü âënh vë
file tham chiãúu âãún mäüt vë trê byte trong mäüt stream.
thiãút kãút thuïc båíi mäüt kyï tæû newline. Nhæng khi caïc doìng naìy âæåüc âoüc vaìo bäü
nhåï trong chãú âäü vàn baín thç caïc haìm thæ viãûn seî tæû âäüng cheìn caïc kyï tæû
newline vaìo stream. Cuîng giäúng nhæ váûy, khi nhæîng doìng âæåüc ghi tæì mäüt
stream vàn baín ra mäüt thiãút bë læu træî, caïc haìm I/O coï thãø thay thãú caïc kyï tæû
newline trong stream bàòng caïc kyï tæû âaî âæåüc âënh nghéa træåïc goüi laì
implementation-defined characters. Bàòng caïch naìy, caïc stream vàn baín cuía C
coï mäüt sæû xuáút hiãûn thêch håüp æïng våïi caïc mäi træåìng, ngay caí khi âënh daûng
cuía dæî liãûu trãn säú caïc thiãút bë læu træî coï thãø khaïc nhau.
Våïi daûng nhë phán, trçnh biãn dëch khäng dæûa trãn sæû diãùn dëch cuía caïc byte. Noï
chè âån giaín laì âoüc vaì ghi caïc bit chênh xaïc nhæ laì baín thán chuïng. Caïc stream
nhë phán âæåüc sæí duûng phäø duûng cho caïc dæî liãûu khäng phaíi laì vàn baín, åí âáy
khäng coï caïc cáúu truïc doìng vaì âiãöu quan troüng laì noï giæî chênh xaïc näüi dung cuía
caïc file. Nãúu ta caím tháúy thuáûn tiãn hån khi giæî væîng caïc cáúu truïc doìng cuía file
thç nãn sæí duûng stream vàn baín. Ba stream chuáøn âãöu âæåüc måí dæåïi chãú âäü vàn
baín.
Thæ viãûn thæûc hiãûn cuía C chæïa thãm mäüt låïp caïc caïch sæí duûng bäü âãûm dæåïi 2
daûng: line buffering vaì block buffering.
Trong line buffering, hãû thäúng seî læu caïc kyï tæû cho âãún khi mäüt kyï tæû newline
âæåüc âæa vaìo, hoàûc laì khi bäü âãûm âáöy, vaì räöi seî gæíi toaìn bäü doìng âãún hãû âiãöu
haình âãø xæí lyï.
Trong block buffering, hãû thäúng seî læu caïc kyï tæû cho âãún khi block âáöy, sau âoï
seî chuyãøn toaìn bäü block cho hãû âiãöu haình. Kêch cåî cuía block âæåüc xaïc âënh båíi
hãû diãöu haình, thæåìng laì 512 hay 1024 byte. Theo màûc âënh, táút caí I/O stream
chè âãún mäüt file sæí duûng bäü âãûm block.
Thæ viãûn I/O chuáøn cuía C coï gäöm mäüt bäü quaín lyï bäü âãûm (buffer manager) noï
giæî caïc bäü âãûm láu trong bäü nhåï. Vç váûy nãúu baûn truy xuáút cuìng mäüt pháön cuía
stream nhiãöu hån mäüt láön thç âáy laì cå häüi täút âãø hãû thäúng traïnh truy xuáút caïc
thiãút bë I/O nhiãöu láön. Tuy nhiãn, chuï yï ràòng âiãöu naìy coï thãø taûo ra váún âãö khi
file âoï âang âæåüc chia xeí cho nhiãöu tiãún trçnh.
Laìm saûch bäü âãûm cuía mäüt stream: int fflush(FILE *stream);
Caïc stream nhë phán thç cuîng hoaìn toaìn giäúng nhæ váûy, nhæng chè thãm vaìo
cuäúi chuäùi naìy mäüt kyï tæû b. Vê duû âãø måí mäüt file nhë phán âãø âoüc thç ta duìng
nhæ sau “rb”, coìn våïi vàn baín ta cuîng coï thãø thãm vaìo kyï tæû t cuäúi, chàóng haûn
“rt”.
Toïm tàõt caïc thuäüc tênh chãú âäü cuía fopen()
r w a r+ w+ a+
File phaíi coï træåïc khi måí 9 9
File cuî seî bë xoaï hãút näüi dung 9 9
Stream coï thãø âoüc 9 9 9 9
Stream coï thãø viãút 9 9 9 9 9
Stream chè coï thãø viãút åí cuäúi 9 9
Haìm fopen() traí vãö mäüt con troí file nãúu viãûc måí thaình cäng, ngæåüc laûi seî traí vãö
con troí NULL.
Vê duû: Haìm sau âãø måí mäüt file coï tãn chè roî, våïi chãú âäü truy xuáút naìo âoï.
#include <stdio.h>
#include <stddef.h>
Duìng haìm naìy âãø måí file test.c theo chãú âäü âoüc.
#include <stdio.h>
#include <stddef.h>
main()
{
extern FILE *open_file();
.
.
}
Vê duû: Sæí duûng getc() vaì putc() âãø sao cheïp file
#include <stdio.h>
#include <stddef.h>
#define FAIL 0
#define SUCCESS 1
if ((fp1=fopen(infile, "rb"))==NULL)
return FAIL;
if ((fp2=fopen(outfile, "wb"))==NULL)
{
fclose(fp1);
return FAIL;
}
while (!feof(fp1))
fputc(fgetc(fp1), fp2);
fclose(fp1);
fclose(fp2);
return SUCCESS;
}
Ta måí caí hai file theo chãú âäü nhë phán båíi vç ta chè âoüc trãn tæìng kyï tæû riãng leí
maì khäng quan tám âãún cáúu truïc doìng cuía file. Haìm naìy thæûc hiãûn âæåüc trãn táút
caí caïc loaûi file.
kyï tæû cuäúi cuìng cuía maíng. Haìm fputs() ghi mäüt maíng chè båíi âäúi säú âáöu tiãn
âãún mäüt stream åí âäúi säú thæï hai.
Vê duû: Viãút laûi haìm copyfile()
#include <stdio.h>
#include <stddef.h>
#define FAIL 0
#define SUCCESS 1
#define LINESIZE 100
if ((fp1=fopen(infile, "r"))==NULL)
return FAIL;
if ((fp2=fopen(outfile, "w"))==NULL)
{
fclose(fp1);
return FAIL;
}
Chuï yï ràòng åí âáy ta måí file theo daûng vàn baín vç ta muäún truy xuáút dæî liãûu theo
tæìng doìng mäüt. Nãúu måí file daûng nhë phán thç haìm trãn coï thãø khäng laìm viãûc
âuïng.
#include <stdio.h>
#include <stddef.h>
#define FAIL 0
#define SUCCESS 1
#define BLOCKSIZE 512
if ((fp1=fopen(infile, "rb"))==NULL)
return FAIL;
if ((fp2=fopen(outfile, "wb"))==NULL)
{
fclose(fp1);
return FAIL;
}
fclose(fp1);
fclose(fp2);
return SUCCESS;
}
Vê duû aïp duûng: 1. Âoüc mäüt file chæïa caïc thäng tin vãö nhán viãn nhæ cáúu truïc
NHANVIEN åí Chæång 8 coï tãn “AG.REC” vaìo mäüt danh saïch liãn kãút.
int *read_file()
{
FILE *fp;
NHANVIEN *pnew;
if ((fp=fopen("AG.REC", "rb")==NULL)
return FAIL;
else
{
pnew=(NHANVIEN *)malloc(sizeof(NHANVIEN);
head= pnew;
while (fread(pnew, sizeof(NHANVIEN),
1, fp))==1)
{
pnew = pnew->next;
pnew = (NHANVIEN *)
malloc(sizeof(NHANVIEN);
}
fclose(fp);
return SUCCESS;
}
int write_file()
{
FILE *fp;
Giaïo Trçnh Ngän Ngæî Láûp Trçnh C 157
Chæång 9, Xuáút Nháûp File
NHANVIEN *p;
int n=0;
if ((fp=fopen("AG.REC", "rb")==NULL)
return FAIL;
for (p=head; p->next!=NULL; n++, p=p->next);
if (n<1){
printf("Danh saïch räùng\n");
exit(1);
}
else
{
fwrite(head, sizeof(NHANVIEN), n, fp);
fclose(fp);
printf("Säú baín ghi: %d\n", n);
}
return SUCCESS;
}
int main()
{
int i;
return 0;
}
Haìm fseek() di chuyãøn bäü âënh vë trê file âãún mäüt kyï tæû âæåüc chè ra trong mäüt
stream. Khai baïo nguyãn máùu fseek() laì:
fseek(FILE *stream, long int kh_cach, int vi_tri);
Ba âäúi säú laì:
stream Con troí file
kh_cach Mäüt khoaíng caïch âæåüc âo theo caïc kyï tæû (coï thãø dæång
hoàûc ám)
vi_tri Vë trê khåíi âáöu âæåüc tênh
Coï ba trë säú âæåüc choün cuía vi_tri:
SEEK_SET Vë trê bàõt âáöu file
SEEK_CUR Vë trê hiãûn thåìi cuía bäü âënh vë file
SEEK_END Vë trê cuäúi file
Chuï yï ràòng vë trê traí vãö cuía ftell() âæåüc tênh tæì âáöu file. Våïi caïc stream nhë phán,
giaï trë traí vãö cuía ftell() âaûi diãûn cho säú kyï tæû tháût sæû kãø tæì âáöu file. Våïi caïc
stream vàn baín giaï trë traí vãö cuía ftell() laì caïc giaï trë caìi âàût âæåüc âaî âënh nghéa
maì chuïng chè coï yï nghéa khi sæí duûng laì giaï trë khoaíng caïch trong mäüt låìi goüi
fseek().
AÏp duûng xáy dæûng haìm filesize() âãø tênh kêch cåî file
long filesize(FILE *stream)
{
long curpos, length;
curpos = ftell(stream);
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fseek(stream, curpos, SEEK_SET);
return length;
}
Ngoaìi haìm fseek() âãø âënh vë âãún vë trê kyï tæû báút kyì trong mäüt stream, ta coï
thãm haìm rewind() âãø âæa bäü chè vë trê vãö âáöu file.
void rewind(FILE *stream);
Låìi goüi haìm sau
rewind( fp );
laì tæång âæång våïi
(void)fseek( fp, 0L, SEEK_SET );
Nhæng åí âáy coï mäüt âiãøm khaïc laì: rewind() xoaï âi maî läùi vaì end-of-file cho caïc
stream vaì khäng traí vãö giaï trë.
âæåüc kiãøm tra thäng hai haìm feof() vaì ferror(). Trong mäüt vaìi træåìng håüp mäüt
haìm I/O traí vãö cuìng mäüt giaï trë våïi end-of-file vaì maî läùi. Trong nhæîng træåìng
håüp naìy ta cáön kiãøm tra mäüt trong nhæîng cåì läùi âãø xem sæû kiãûn naìo thæûc sæû âaî
xuáút hiãûn.
Caïc haìm sau âáy kiãøm tra cåì läùi vaì cåì end-of-file cho mäüt stream âæåüc chè ra vaì
traí vãö mäüt trong bäún giaï trë càn cæï trãn caïc kãút quaí: haìm clearerr() thiãút láûp caí
hai giaï trë cåì vãö 0. Ta phaíi chuí âäüng thiãút láûp caïc giaï trë cåì bàòng clearerr(),
chuïng seî khäng tæû âäüng thiãút láûp laûi khi ta âoüc chuïng, chuïng cuîng khäng tæû
thiãút láûp vãö 0 nãúu coï caïc låìi goüi I/O kãú tiãúp. Chuïng âæåüc khåíi âäüng bàòng 0 khi
stream måí, nhæng chè coï mäüt caïch âãø thiãút láûp laûi chuïng vãö 0 bàòng clearerr().
Vê duû:
/* Nãúu caí hai cåì khäng thiãút láûp thç stat = 0.
* Nãúu cåì läùi, nhæng khäng phaíi eof, stat = 1.
* Nãúu cåì eof, nhæng khäng phaíi läùi, stat = 2.
* Nãúu caí hai cåì âæåüc thiãút láûp, thç stat = 3.
*/
#include <stdio.h>
#define EOF_FLAG 1
#define ERR_FLAG 2
FILE *fp;
fp = fopen("PERROR.DAT", "r");
if (!fp)
perror("Khäng thãø måí file\n");
return 0;
}
# BIÃÚN errno
Ngoaìi hai cåì baïo end-of-file vaì läùi, coìn coï thãm mäüt biãún toaìn cuûc coï tãn errno
âæåüc sæí duûng båíi mäüt säú êt caïc haìm I/O âãø ghi caïc läùi. Âáy laì sæû kãú thæìa tæì
UNIX, errno laì mäüt biãún nguyãn âënh nghéa trong errno.h. Biãún errno âæåüc
duìng chuí yãúu cho caïc haìm toaïn hoüc; ráút êt caïc haìm I/O sæí duûng errno.
mode YÏ nghéa
S_IREAD Cho pheïp âoüc
S_IWRITE Cho pheïp ghi
S_IWRITE | S_IREAD Cho pheïp âoüc vaì ghi
Traí vãö giaï trë khäng ám nãúu thaình cäng, vaì âoï chênh laì giaï trë âãø truy cáûp lãn
file væìa måí. Nãúu läùi, seî traí vãö -1 (EOF).
Vê duû: Taûo file text våïi open()
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
int main(void)
{
int handle;
char msg[] = "Hello world";
if ((handle = open("TEST.$$$",
O_CREAT | O_TEXT)) == -1)
{
perror("Error:");
return 1;
}
write(handle, msg, strlen(msg));
close(handle);
return 0;
}
Xoaï file
int unlink( const char *file_name );
Xoaï mäüt file khoíi thæ muûc âæåüc chè ra
Âoïng file
close( int handle );
9.10.2 VÊ DUÛ
Viãút chæång trçnh thæûc hiãûn tæång tæû lãûnh COPY cuía DOS.
#include <fcntl.h>
#include <sys\stat.h>
#define BUF_SIZE 4096
char buff[BUF_SIZE];
if (argc != 3) {
printf("Usage: %s <source> <dest>\n",
argv[0]);
exit(1);
}
if ((ihandle = open(argv[1],
O_RDWR | O_BINARY)) == -1)
{
perror("Error:");
exit(1);
}
if ((ohandle = open(argv[2],O_CREAT |
O_WONLY | O_BINARY, S_IWRITE)) == -1)
{
perror("Error:");
exit(1);
}
while ((bytes = read(ihandle, buff,
BUF_SIZE))>0)
write(ohandle, buff, bytes);
close(ihandle);
close(ohandle);
return 0;
}
BAÌI TÁÛP
1. Viãút chæång trçnh coï sæí duûng cáu lãûnh tiãön xæí lyï #include.
2. Viãút mäüt haìm goüi laì compress() âãø xoïa táút caí caïc khoaíng tràõng thæìa tæì mäüt
file nguäön C. (Chuï yï ràòng: khäng xoïa caïc khoaíng tràõng trong hàòng kyï tæû
vaì hàòng chuäùi).
3. Viãút chæång trçnh âãø kiãøm tra tênh âuïng âàõn cuía caïc càûp dáúu ngoàûc vaì moïc
trong mäüt file nguäön C.
4. Viãút chæång trçnh âãø âãúm säú caïc kyï tæû, caïc tæì, vaì caïc doìng trong mäüt file.
5. Viãút chæång trçnh âãø copy táút caí caïc file trãn doìng lãûnh ra stdout.
6. Viãút chæång trçnh cho pheïp NSD nháûp dæî liãûu vaìo file chæïa caïc cáúu truïc
VITALSTAT âæåüc âënh nghéa åí chæång 8.
7. Viãút chæång trçnh âoüc caïc kyï tæû tæì thiãút bë nháûp chuáøn (standard input) vaì
sao cheïp ra thiãút bë xuáút chuáøn (standard output), chuyãøn mäùi chuäùi ‘\r’ ‘\n’
thaình ‘\n’.
8. Viãút chæång trçnh tæång tæû baìi 7, nháûn hai âäúi säú doìng lãûnh:
-from srcstr
-to deststr
Mäùi xuáút hiãûn cuía srcstr åí doìng dæî liãûu vaìo seî âæåüc chuyãøn thaình deststr åí
doìng dæî liãûu ra.
9. Viãút chæång trçnh måí mäüt file âæåüc chè ra åí doìng lãûnh vaì in maìn hçnh theo
thæï tæû ngæåüc laûi (âaío nngæåüc näüi dung file).
10. Viãút chæång trçnh âãø âoüc báút kyì file naìo trãn doìng lãûnh (ngay caí file nhë
phán) vaì in ra chè nhæîng daîy coï êt nháút hai kyï tæû thuäüc nhoïm caïc kyï tæû in
âæåüc ( ‘a’... ‘z’, ‘A’...‘Z’, ' ', ‘0’...‘9’).