Monday, July 20, 2015


Standard I/O Library là thư viện vào/ra chuẩn, có file header là stdio.h. Thư viện cung cấp một tập các low-level I/O system calls. Như đã trình bày ở phần Low-Level File Access, file descriptor là thông số liên hệ với file/device được mở ra để thao tác; trong thư viện stdio, thông số stream có ý nghĩa tương đương với file descriptor, và stream được thể hiện qua cấu trúc FILE.
Ba file stream được tự động mở khi hệ thống khởi động được liệt kê dưới đây:
+ 0: Standard input, stdin (keyboard, mouse)
+ 1: Standard output, stdout (screen)
+ 2: Standard error, stderr (screen)

Trong bài viết này, một số hàm trong stdio dưới đây được đề cập đến:
+ fopen , fclose
+ fread , fwrite
+ fflush
+ fseek
+ fgetc , getc , getchar
+ fputc , putc , putchar
+ fgets , gets
+ fputs, puts

1. fopen
 #include <stdio.h>  
 FILE *fopen(const char *filename, const char *mode);  

+ filename
Đường dẫn đến file cần mở
+ mode
Chế độ mở file để làm gì

mode Description
"r" or "rb" Open for reading only
"w" or "wb" Open for writing, truncate to zero length
"a" or "ab" Open for writing, append to end of file
"r+" or "rb+" or "r+b" Open for update (reading and writing)
"w+" or "wb+" or "w+b" Open for update, truncate to zero length
"a+" or "ab+" or "a+b" Open for update, append to end of file

Với "r" chỉ có thể mở được file text (Ex: filename.txt); "b" nghĩa là binary file, với "rb" có thể mở file với đuôi mở rộng bất kỳ để đọc nội dung (Ex: filename.c).
+return
Trả về con trỏ FILE * non-null, trả về null nếu thất bại.

2. fread
 #include <stdio.h>  
 size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);  

+ ptr
Buffer chứa dữ liệu đọc được
+ size
Kích thước tính bằng byte của mỗi phần tử
+ nitems
Số phần tử muốn đọc
+ stream
Stream để đọc
+ return
Trả về số phần tử (items) đã đọc được, return items <= nitems, số byte đã đọc được: (return items) * size

Ex:
fread.c
 #include <stdio.h>  
 #include <string.h>  
   
 int main()  
 {  
   FILE *fp = NULL;  
   int nread;  
   char buffer[100];  
   memset(buffer, '\0', sizeof(buffer));  
   
   /* Open file for both reading */  
   fp = fopen("testfile.dt", "rb");  
   if(!fp) return 1;  
   
   /* Read and display data */  
   nread = fread(buffer, sizeof(char), 100, fp);  
   printf("nread: %d, str: %s\n", nread, buffer);  
   
   memset(buffer, '\0', sizeof(buffer));  
   nread = fread(buffer, sizeof(char)*2, 10, fp);  
   printf("nread: %d, str: %s\n", nread, buffer);  
   
   fclose(fp);  
   return(0);  
 }  
   

3. fwrite
 #include <stdio.h>  
 size_t fwrite (const void *ptr, size_t size, size_t nitems, FILE *stream);  

+ ptr
Buffer chứa dữ liệu để ghi xuống stream
+ size
Kích thước tính bằng byte của mỗi phần tử
+ nitems
Số phần tử muốn ghi
+ stream
Stream để ghi
+ return
Trả về số phần tử (items) đã ghi được, return items <= nitems, số byte đã ghi được: (return items) * size

Ex:
fwrite.c
 /* fwrite example : write buffer */  
 #include <stdio.h>  
   
 int main ()  
 {  
  FILE * pFile;  
  char buffer[] = { 'x' , 'y' , 'z' };  
  pFile = fopen ("myfile.bin", "wb");  
  fwrite (buffer , sizeof(char), sizeof(buffer), pFile);  
  fclose (pFile);  
  return 0;  
 }  

4. fclose
 #include <stdio.h>  
 int fclose(FILE *stream);  

+ stream
Stream muốn đóng.
+ return
Trả về 0 nếu đóng thành công.

5. fflush
 #include <stdio.h>  
 int fflush(FILE *stream);  

fflush là thao tác thường được dùng sau các thao tác ghi dữ liệu xuống stream như fwrite để chắc chắn rằng mọi dữ liệu muốn ghi sẽ được hoàn thành trước khi bạn muốn thực hiện các thao tác khác với stream.
+ stream
Stream muốn flush.
+ return
Trả về 0 nếu thành công.

Ex:
fflush.c
 /* fflush example */  
 #include <stdio.h>  
 char mybuffer[80];  
 int main()  
 {  
   FILE * pFile;  
   pFile = fopen ("example.txt","r+");  
   if (pFile == NULL) perror ("Error opening file");  
   else {  
    fputs ("test",pFile);  
    fflush (pFile);  // flushing or repositioning required  
    fgets (mybuffer,80,pFile);  
    puts (mybuffer);  
    fclose (pFile);  
    return 0;  
  }  
 }  

6. fseek
fseek sẽ di chuyển con trỏ đến vị trí khác trong stream đang được mở.
 #include <stdio.h>  
 int fseek(FILE *stream, long int offset, int whence);  

+ stream
Stream đang mở
+ offset
Vị trí sẽ nhảy đến, tính bằng byte
+ whence
Điểm mốc để tính vị trí nhảy đến offset, có giá trị tương tự như với lseek.
+ return
Trả về 0 nếu thành công; -1 nếu lỗi, thông báo lỗi lưu trong errno.

Ex:
fseek.c
 /* fseek example */  
 #include <stdio.h>  
   
 int main ()  
 {  
  FILE * pFile;  
  pFile = fopen ( "example.txt" , "wb" );  
  fputs ( "This is an apple." , pFile );  
  fseek ( pFile , 9 , SEEK_SET );  
  fputs ( " sam" , pFile );  
  fclose ( pFile );  
  return 0;  
 }  

7. fgetc, getc, and getchar
 #include <stdio.h>  
 int fgetc(FILE *stream);  
 int getc(FILE *stream);  
 int getchar();  

fgetc và getc là tương đương, đều đọc từng byte từ stream (mỗi lần đọc 1 byte).
getchar() tương đương với getc(stdin), đọc từng byte từ stdin.

+ stream
Stream để đọc
+ return
Trả về ký tự đọc được theo bảng mã ASCII (Ex: return 65 tương đương với ký tự A), trả về EOF nếu hết file hoặc lỗi.

Ex:
fgetc.c
 /* fgetc example: money counter */  
 #include <stdio.h>  
 int main ()  
 {  
  FILE * pFile;  
  int c;  
  int n = 0;  
  pFile=fopen ("myfile.txt","r");  
  if (pFile==NULL) perror ("Error opening file");  
  else  
  {  
   do {  
    c = fgetc (pFile);  
    if (c == '$') n++;  
   } while (c != EOF);  
   fclose (pFile);  
   printf ("The file contains %d dollar sign characters ($).\n",n);  
  }  
  return 0;  
 }  

getc.c
 /* getc example: money counter */  
 #include <stdio.h>  
 int main ()  
 {  
  FILE * pFile;  
  int c;  
  int n = 0;  
  pFile=fopen ("myfile.txt","r");  
  if (pFile==NULL) perror ("Error opening file");  
  else  
  {  
   do {  
    c = getc (pFile);  
    if (c == '$') n++;  
   } while (c != EOF);  
   fclose (pFile);  
   printf ("File contains %d$.\n",n);  
  }  
  return 0;  
 }  

getchar.c
 /* getchar example : typewriter */  
 #include <stdio.h>  
   
 int main ()  
 {  
  int c;  
  puts ("Enter text. Include a dot ('.') in a sentence to exit:");  
  do {  
   c=getchar();  
   putchar (c);  
  } while (c != '.');  
  return 0;  
 }  

8. fputc, putc, and putchar
 #include <stdio.h>  
 int fputc(int c, FILE *stream);  
 int putc(int c, FILE *stream);  
 int putchar(int c);  

Ngược lại mới các hàm ở mục 7, các hàm ở mục 8 sẽ ghi từng byte xuống stream (mỗi lần ghi 1 byte), putchar ghi byte xuống stdout.

+ c
Ký tự (byte) sẽ được ghi
+ stream
Strem để ghi xuống
+ return
Trả về ký tự vừa được ghi nếu thành công, trả về EOF nếu lỗi.

Hàm putchar ghi byte xuống stdout.

Ex:
fputc.c
 /* fputc example: alphabet writer */  
 #include <stdio.h>  
   
 int main ()  
 {  
  FILE * pFile;  
  char c;  
   
  pFile = fopen ("alphabet.txt","w");  
  if (pFile!=NULL) {  
   
   for (c = 'A' ; c <= 'Z' ; c++)  
    fputc ( c , pFile );  
   
   fclose (pFile);  
  }  
  return 0;  
 }  

putc.c
 /* putc example: alphabet writer */  
 #include <stdio.h>  
   
 int main ()  
 {  
  FILE * pFile;  
  char c;  
   
  pFile=fopen("alphabet.txt","wt");  
  for (c = 'A' ; c <= 'Z' ; c++) {  
   putc (c , pFile);  
   }  
  fclose (pFile);  
  return 0;  
 }  

putchar.c
 /* putchar example: printing the alphabet */  
 #include <stdio.h>  
   
 int main ()  
 {  
  char c;  
  for (c = 'A' ; c <= 'Z' ; c++) putchar (c);  
   
  return 0;  
 }  

9. fgets and gets
 #include <stdio.h>  
 char *fgets(char *s, int n, FILE *stream);  
 char *gets(char *s);  

fgets nhiều byte từ stream (khác với fgetc chỉ đọc 1 byte):
+ s
Buffer để chứa chuỗi ký tự được đọc từ stream.
+ n
Có tối đa (n-1) byte sẽ được đọc, byte cuối cùng dành cho ký tự new line '\0' sẽ được chèn vào liền sau byte cuối cùng. Có 3 điều kiện để fgets kết thúc việc đọc ghi đatj ít nhất 1 trong 3 điều kiện sau:
    - Đọc đủ (n-1) byte
    - Chưa đọc đủ (n-1) nhưng gặp ký tự new line
    - Chưa đọc đủ (n-1) nhưng hết file (gặp End-Of-File - EOF)
+ stream
Stream để đọc.
+ return
Trả về con trỏ s nếu thành công, trả về NULL nếu gặp EOF hoặc có lỗi xảy ra.

gets đọc nhiều byte từ stdin (khác với getc chỉ đọc 1 byte)
+ Buffer để chứa chuỗi ký tự được đọc từ stdin.
+ return
Trả về con trỏ s nếu thành công, trả về NULL nếu gặp EOF hoặc có lỗi xảy ra.

Ex:
fgets.c
 /* fgets example */  
 #include <stdio.h>  
   
 int main()  
 {  
   FILE * pFile;  
   char mystring [100];  
   
   pFile = fopen ("testfile.txt" , "r");  
   if (pFile == NULL) perror ("Error opening file");  
   else {  
     if ( fgets (mystring , 10 , pFile) != NULL )  
       puts (mystring);  
     fclose (pFile);  
   }  
   return 0;  
 }  
   

gets.c
 /* gets example */  
 #include <stdio.h>  
   
 int main()  
 {  
   char string [256];  
   printf ("Insert your full address: ");  
   gets (string);   // warning: unsafe (see fgets instead)  
   printf ("Your address is: %s\n",string);  
   return 0;  
 }  
   

10. fputs, puts
 # include <stdio.h>  
 int fputs ( const char * str, FILE * stream );  
 int puts ( const char * str );  

fputs ghi chuỗi nhiều ký tự (nhiều byte) xuống stream, puts ghi chuỗi ký tự xuống stdout.
+str
Buffer chứa chuỗi ký tự để ghi.
+ stream
Stream để ghi xuống.
+ return
Trả về số không âm ( > 0) nếu thành công, trả về EOF nếu lỗi.

Ex:
fputs.c
 /* fputs example */  
 #include <stdio.h>  
   
 int main ()  
 {  
   FILE * pFile;  
   char sentence [256];  
   
   printf ("Enter sentence to append: ");  
   fgets (sentence,256,stdin);  
   pFile = fopen ("mylog.txt","a");  
   fputs (sentence,pFile);  
   fclose (pFile);  
   return 0;  
 }  

puts.c
 /* puts example : hello world! */  
 #include <stdio.h>  
   
 int main ()  
 {  
  char string [] = "Hello world!";  
  puts (string);  
 }  


Leave a Reply

Subscribe to Posts | Subscribe to Comments

- Copyright © Lập trình hệ thống nhúng Linux . Powered by Luong Duy Ninh -