Lập trình Fortran xuất và nhập dữ liệu
Chơng : Nhập xuất liệu Đ1 Khái niệm chung Khái niệm :Trớc đà xét việc nhập liệu từ bàn phím Trong nhiều trờng hợp thực tế , để thuận lợi , phải nhập liệu từ tập tin đĩa Các hàm th viện C cho phép truy cập tập tin chia cấp khác : - hàm cấp hàm ë cÊp thÊp nhÊt , truy cËp trùc tiÕp ®Õn tập tin đĩa.C không cung cấp vùng nhớ đệm cho hàm - hàm cấp hàm truy xuất tập tin cao , chúng đợc C cung cấp vùng nhớ đệm Đối với hàm cấp , tập tin đợc xem khối byte liên tục muốn truy cập mẫu tin cụ thể phải tính toán địa mẫu tin nh công việc vất vả Ngoài phải cung cấp vùng nhớ đệm cho kiểu đọc ghi Đối với hàm cấp hai công việc nhẹ nhàng : - trình biên dịch tự động cung cấp vùng kí ức đệm cho chúng - truy xuất mẫu tin mà không gặp khó khăn nh với hàm cấp Trong C , thông tin cần thiết cho hàm xuất nhập cấp đợc đặt tập tin stdio.h thông tin hàm nhËp xuÊt cÊp th× ë tËp tin io.h Stream tập tin : Ta phải phân biệt hai thuật ngữ stream file Hệ thống xt nhËp cđa C cung cÊp mét kh«ng gian t−ëng tợng ngời lập trình thiết bị đợc dùng Cấp trung gian tởng tợng gọi stream thiết bị cụ thể tập tin a C¸c streams : Trong m¸y tÝnh ta dïng loại stream : văn nhị phân Một stream văn loạt kí tự đợc tổ chức thành dòng mà dòng đợc kết thúc kÝ tù xuèng dßng newline(“\n”) Khi ghi , mét kí tự chuyển dòng LF(mà 10) đcợ chuyển thành kí tự CR( mà 13) LF Khi đọc kí tự liên tiếp CR LF tập tin chØ cho ta mét kÝ tù LF Mét stream nhị phân loạt byte a Các tập tin : Trong C ,một tập tin khái niệm logic mà hệ thống áp dụng cho thứ từ tập tin đĩa terminal Khi bắt đầu thực chơng trình , máy tính mở stream văn đà đợc định nghĩa trớc stdin , stdout stderr Đối với hầu hết hệ thống , thiết bị console Đ2 Nhập xuất chuẩn Nhập xuất kí tự , chuỗi kí tự , định dạng ghi : Nhập xuất cấp 2(nhập xuất chuẩn ) cung cấp cách đọc ghi liệu khác (ngợc lại nhập xuất câp1 dùng cách này) Trớc hết liệu đọc ghi lần kí tự , tơng tự nh cách làm việc putchar() getche() để đọc liệu từ bàn phím hiển thị lên hình Thứ hai , liệu nhập xuất theo chuỗi dùng hàm gets() puts() Thứ ba , liệu đợc nhập xuất theo khuôn dạng hàm fprintf() fscanf() Thứ t , liệu đợc đọc ghi theo khối có chiều dài cố định thờng dùng lu trữ mảng hay cấu trúc hàm fread() fwrite() Tóm lại : Các hàm dùng chung cho hai kiểu nhị phân văn fopen : dïng më tËp tin 21 fclose : ®ãng tập tin fclose : đóng tất tập tin fflush : dùng làm vùng đệm tập tin flushall : dùng làm vùng đệm tất tập tin ferror : cho biết có lỗi (khác không) hay lỗi ( 0) perror : thong báo lỗi hình foef : cho biết cuối tập tin hay cha unlink remove : dùng để loại tập tin đĩa fseek : di chuyển trỏ đến vị trí tập tin ftell : cho biết vị trí trỏ Các hàm nhập xuất kí tự putc fputc : nhËp kÝ tù vµo tËp tin getc vµ fgetc : ®äc kÝ tù tõ tËp tin fprintf : dïng ghi liệu định dạng lên tập tin fscanf : dùng đọc liệu định dạng từ tập tin fputs : dùng ghi chuỗi lên tập tin fgets : dùng đọc chuỗi từ tập tin Các hàm dùng cho kiểu xuất nhập nhị phân putw : dùng ghi số nguyên hai byte lên tập tin gets : dùng đọc sè nguyªn hai byte tõ tËp tin fwrite : dïng ghi mét mÉu tin lªn tËp tin fread : dïng đọc mẫu tin từ tập tin 2.Dạng văn dạng nhị phân : Cách khác để phân loại thao tác nhập xuất tập tin đợc mở theo kiểu văn hay nhị phân Điểm khác biệt hai loại kí tự newline end of line Điểm thứ hai để phân biệt hai kiểu tập tin là cách lu trữ số vào đĩa Đối với dạng văn số đợc lu trữ thành chuỗi kí tự dạng nhị phân số đợc lu nh− bé nhí , nghÜa lµ dïng hai byte cho số nguyên byte cho số float Nhập xuất chuẩn : Chơng trình dùng hàm nhập xuất cấp thờng dễ hiểu nªn chóng ta sÏ nghiªn cøu tr−íc a NhËp xuất kí tự : Để nhập kí tự vào tập tin ta dùng hàm putc() hay fputc().Để đọc kí tự tõ tËp tin ta dïng hµm getc() hay fgetc() Chơng trình ví dụ tạo lập kí tự cách gõ vào bàn phím lần kí tự ghi vào tập tin đĩa Chơng trình dùng hàm fopen() để mở tập tin , dùng hàm putc() để ghi lên tập tin , dùng kí tự enter để kết thúc chơng trình Chơng trình 3-1 : #include #include void main() { FILE *fp; char ch; printf(“Nhap cac ki tu : “); fp=fopen("textfile","w"); while ((ch=getche())!='\r') putc(ch,fp); fclose(fp); } 22 b Më mét tËp tin : Tr−íc ghi mét tËp tin lên đĩa ta phải mở tập tin đà Để mở tập tin , trớc hết ta phải khai b¸o mét trá chØ tíi FILE FILE structure chứa đựng thông tin cấu tróc cđa tËp tin vÝ dơ nh− kÝch th−íc , vị trí đệm liệu hành Cấu trúc FILE đợc khai báo stdio.h nên ta cần include tập tin Ngoài stdio.h xác định tên biến khác đợc dùng chơng trình hớng đến tập tin Do chơng trình ta có câu lệnh : FILE *fp ; Sau ®ã ta më tËp tin b»ng lƯnh : fopen(“textfile”,”w”); Khi viÕt nh− vËy sÏ lµm cho hƯ điều hành biết mở tập tin tên textfile th mục hành để viết lên tập tin (nhờ w) Ta cho tên ®−êng dÉn ®Çy ®đ nÕu mn më tËp tin ë th mục Hàm fopen() trả trá chØ ®Õn cÊu tróc FILE cho tËp tin trỏ đợc cất giữ biến fp Chuỗi w đợc gọi kiểu , có nghĩa ghi lên tập tin Các kiểu mở tập tin : r,rt mở để đọc , tập tin phải có đĩa w,wt mở để ghi , đĩa đà có tập tin nội dung bị ghi đè , cha có tập tin đợc tạo lập a,at mở để nối thêm, thông tin đợc ghi vào cuối tập tin cũ đà có tập tin hay tạo tập tin r+,r+t mở để vừa đọc ghi , tập tin phải có ®Üa “rb” më mét tËp tin ®Ó ®äc theo kiÓu nhị phân Tập tin phải có sẵn đĩa r+b mở tập tin để đọc theo kiểu nhị phân Tập tin phải có sẵn đĩa w+,w+t mở để vừa đọc ghi , nội dung tập tin đà có đĩa bị ghi đè lên wb mở để ghi theo kiểu nhị phân , đĩa đà có tập tin nội dung bị ghi đè , cha có tập tin đợc tạo lập a+,a+t mở để đọc nối thêm , tập tin cha có đợc tạo ab mở để đọc nối thêm theo kiểu nhị phân , tập tin cha có đợc tạo c Ghi lên tập tin : Khi tập tin đà đợc mở , ta ghi lên tập tin kí tự cách dùng hàm : putc(ch,fp) Hàm putc() tơng tự hàm putch() putchar() Hàm putc() ghi lên tập tin có cấu trúc FILE đợc ấn định biến fp nhận đợc mở tập tin Tiến trình ghi đợc tiến hành nhấn enter d Đóng tập tin : Khi không đọc ghi ta cần đóng tập tin Câu lệnh đóng tập tin : fclose(fp); Ta báo cho hệ thống biết cần đóng tập tin fp e Đọc tËp tin : NÕu ta cã thĨ ghi lªn tËp tin ta đọc từ tập tin Ta có ví dụ sau : Chơng trình 3-2 : #include #include main() { FILE *fp; int ch; clrscr(); fp=fopen("textfile","r"); while ((ch=getc(fp))!=EOF) 23 printf("%c",ch); fclose(fp); getch(); } f Kết thúc tập tin : Sự khác nhâu chủ yếu chơng trình đọc ghi chơng trình đọc phải phân biệt đợc đâu kí tự EOF Nó kí tự àm số nguyên hệ điều hành gửi tới Khi hÕt tËp tin ta gỈp m· kÕt thóc tËp tin EOF (định nghĩa stdio.h -1 ) hàm foef() cho trị khác không Ngời ta chọn -1 làm mà kết thúc cha gặp cuối tập tin đọc đợc byte mà mà nằm khoảng 0-255 Nh giá trị -1 không trùng với kí tự nào đợc đọc từ tập tin Trong chơng trình đọc hiển thị kí tự tìm kiếm mộ giá trị -1 hay EOF Khi thấy giá trị , chơng trình kết thúc Chúng ta dùng biến nguyên cất giữ kí tự đọc đợc , ta hiểu dấu EOF nh trị nguyên có trị lµ -1 NÕu dïng mét biÕn kiĨu char , chúg ta dùng tất kí tự từ 255 - tổ hợp bit Do dùng biến nguyên , ta bảo đảm có giá trị 16 bit -1 , dấu EOF g Sự phiền phức mở tập tin : Hai chơng trình ta trình bày có lỗi tiểm ẩn Nếu tập tin đà đợc định không mở đợc chơng trình không chạy Lỗi tập tin cha có (khi đọc) hay đĩa không đủ chỗ(khi ghi) Do vấn đề phải kiểm tra xem tập tin có mở đợc hay không , tập tin không mở đợc hàm fopen() trả trị 0(0 NULL stdio.h) Khi C coi địa hợp lệ Nh ta viết lại chơng trình nh sau Chơng trình 3-3 : #include #include #include void main() { FILE *fp; int ch; clrscr(); if ((fp=fopen("file","r"))==NULL) { printf("Khong mo duoc tap tin\n"); getch(); exit(1); } while ((ch=getc(fp))!=EOF) printf("%c",ch); fclose(fp); } h §Õm sè kÝ tự : Khả đọc ghi tập tin sở kí tự cho phép triển khai số ứng dụng Chúng ta xem xét chơng trình đếm số kí tự sau : Chơng trình 3-4 : #include #include main(int argc,char *argv) { FILE *fp; 24 char string[8]; int count = 0; clrscr(); if (argc!=2) { printf("Format c:\ "); getch(); exit(1); } if ((fp=fopen(argv[1],"r"))==NULL) { printf("Khong mo duoc tap tin\n"); getch(); exit(1); } while (getc(fp)!=EOF) count++; fclose(fp); printf("Tap tin %s co %d ki tu",argv[1],count); getch(); } i §Õm sè tõ : Ta sửa chơng trình thành chơng trình đếm số từ Chơng trình 3-5 : #include #include #include main(int argc,char *argv[]) { FILE *fp; char ch,string[81]; int count = 0; int white=1; clrscr(); if (argc!=2) { printf(" Format c:\ \n"); getch(); exit(1); } if ((fp=fopen(argv[1],"r"))==NULL) { printf("Khong mo duoc tap tin\n"); getch(); exit(1); } while ((ch=getc(fp))!=EOF) switch(ch) { case ' ': /*nÕu cã dÊu trèng , dßng míi hay tab*/ 25 case '\t': case '\n': white++; break; default:if(white) { white=0; count++; } } fclose(fp); printf("Tap tin %s co %d tu",argv[1],count); getch(); return 0; } k.Vào chuỗi : Đọc hay ghi chuỗi tập tin tơng tự nh đọc hay ghi kí tự riêng lẻ Ta xét chơng trình ghi chuỗi Chơng trình 3-6 : #include #include #include #include void main() { FILE *fp; char string[8]; clrscr(); if ((fp=fopen("a.txt","w"))==NULL) { printf("Khong mo duoc tap tin\n"); getch(); exit(1); } while (strlen(gets(string))>0) { fputs(string,fp); fputs("\n",fp); } fclose(fp); } Trong chơng trình chuỗi kết thúc cách gõ enter kết thúc chơng trình cách gõ enter đầu dòng Do fputs() không tự động thêm vào mà kết thúc để chuyển dòng nên ta phải thêm vào tập tin mà Chơng trình đọc chuỗi từ tập tin : Chơng trình 3-7 : #include #include #include #include void main() 26 { FILE *fp; char string[81]; clrscr(); if ((fp=fopen("a.txt","r"))==NULL) { printf("Khong mo duoc tap tin\n"); getch(); exit(1); } while (fgets(string,81,fp)!=NULL) printf("%s",string); fclose(fp); getch(); } Hµm fgets() nhận đối số : địa nơi đặt chuỗi , chiều dài tối đa chuỗi , trá chØ tíi tËp tin l VÊn ®Ị sang dòng : Trong chơng trình đếm kí tự ta thấy số kí tự đếm đợc nhỏ số byte có tập tin nhận đợc b»ng lƯnh dir cđa DOS Khi ta ghi mét tập tin văn vào đĩa , C tự động ghi vào đĩa hai mà CR LF gặp mà sang dòng \n Ngợc lại đọc tập tin từ đĩa , mà CR LF đợc tổ hợp thành mà sang dòng Chơng trình sau minh hoa thêm kĩ thuật vào chuỗi , nội dung tơng tự lệnh type DOS Chơng trình 3-8 : #include #include #include main(int argc,char *argv[]) { FILE *fp; char string[81]; clrscr(); if (argc!=2) { printf("Format c:\ "); getch(); exit(1); } if ((fp=fopen(argv[1],"r"))==NULL) { printf("Khong mo duoc tap tin\n"); getch(); exit(1); } while (fgets(string,81,fp)!=NULL) printf("%s",string); fclose(fp); getch(); return 0; 27 } m Các tập tin chuấn máy in : Trên ta đà nói đến cách thức tiÕp nhËn mét trá tham chiÕu dÕn mét tËp tin đĩa hàm fopen() , C định nghĩa lại tê chuẩn tập tin chuẩn nh sau : Tên in out err aux prn Thiết bị Thiết bị vào chuẩn (bàn phím) Thiết bị chuẩn (màn hình) Thiết bị lỗi chuẩn (màn hình) Thiết bị phụ trợ chuẩn(cổng nối tiếp) Thiết bị in chuẩn (máy in) Ta dùng tên để truy cập đến thiết bị Chơng trình sau dùng hàm fgets(0 fputs() để in nội dung tập tin máy in Chơng trình 3-9 : #include #include #include main(int argc,char *argv[]) { FILE *fp1,*fp2; char string[81]; clrscr(); if (argc!=2) { printf("Format c:\ "); getch(); exit(1); } if ((fp1=fopen(argv[1],"r"))==NULL) { printf("Khong mo duoc tap tin\n"); getch(); exit(1); } if ((fp2=fopen("prn","w"))==NULL) { printf("Khong mo duoc may in\n"); getch(); exit(1); } while (fgets(string,81,fp1)!=NULL) fputs(string,fp2); fclose(fp1); fclose(fp2); getch(); return 0; } Trong chơng trình máy in đợc coi tập tin có tên prn 28 n Nhập xuất định dạng : Trớc ta ®· ®Ị cËp ®Õn nhËp xt kÝ tù Những số có định dạng ghi lên đĩa nh kí tự Ta xét chơng trình sau Chơng trình 3-10 : #include #include main() { FILE *p; int i,n; float x[4],y[4]; clrscr(); p=fopen("test.txt","w"); printf("Cho so cap so can nhap n = "); scanf("%d",&n); fprintf(p,"%d\n",n); printf("Cho cac gia tri x va y\n"); for (i=0;i