Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 18 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
18
Dung lượng
307,59 KB
Nội dung
Xuất nhập (input/output) EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Khái niệm Người lập trình thường xuyên phải làm việc với số thiết bị vào hình, bàn phím, file, máy in,… Với chương trình, có: Đầu chuẩn stdout: mặc định hình console, coi file ảo ghi, định nghĩa lại file đĩa máy in Đầu chuẩn cho lỗi stderr: tương tự stdout, thường dùng để ghi dòng lỗi gặp phải chương trình Đầu vào chuẩn stdin: mặc định bàn phím, coi file ảo đọc, định nghĩa lại file đĩa EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Mở đầu Xuất stdout Xuất ký tự: int putchar(int c); Xuất dòng ký tự: int puts(const char* s); Xuất chuỗi theo định dạng: int printf(const char* format, ); Nhập từ stdin Đọc dòng ký tự: char* gets(char* s); Đọc ký tự: int getchar(); Đọc chuỗi theo định dạng: int scanf(const char* format, ); EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Xuất nhập từ file Kiểu file: typedef struct { … } FILE; Trình tự thao tác với file: Mở/tạo file Đọc/ghi liệu Đóng Trong kiểu FILE có trường lưu thơng tin vị trí đọc/ghi file, gọi trỏ file Mở file: FILE* fopen(const char* fname, const char* mode); mode Ý nghĩa mode Ý nghĩa "r" "r+" Cho phép đọc ghi "w" Chỉ cho phép ghi, xoá nội dung file cũ có tạo file chưa có "w+" Cho phép đọc ghi, xoá nội dung file cũ có tạo file chưa có "a" Chỉ cho phép ghi, trỏ trỏ đến cuối file để ghi tiếp tạo file chưa có "a+" Cho phép đọc ghi, trỏ trỏ tới cuối file để ghi tiếp tạo file chưa có "t" Chỉ cho phép đọc Đọc/ghi dạng văn (text) "b" Đọc/ghi dạng nhị phân (binary) EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Chú ý với việc mở file Việc mở file khơng thành công trả NULL cần kiểm tra giá trị trả fopen() để biết mở file thành cơng khơng Các lý khiến mở file không thành công: Mở file để đọc mà file khơng tồn Người dùng khơng có quyền File mở với chế độ hạn chế chương trình Có nhiều file mở (hệ điều hành có giới hạn số file mở đồng thời) Các file mở với hàm fopen() không hạn chế mở lại EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Mở file hạn chế mở lại Đôi ta khơng muốn chương trình khác can thiệp vào file ta mở để đọc/ghi FILE* _fsopen(const char* fname, const char* mode, int shflag); shflag: cờ cho phép file mở lại hay không #include Ý nghĩa shflag _SH_DENYNO Không hạn chế _SH_DENYRD Hạn chế mở lại với chế độ đọc _SH_DENYWR Hạn chế mở lại với chế độ ghi _SH_DENYRW Hạn chế mở lại với chế độ đọc ghi Lưu ý: Hàm có MS Visual C EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Ghi vào file File văn (text) nhị phân (binary) File văn bản: số ký tự đặc biệt chuyển đổi '\n' "\r\n", xử lý ký tự hết file thích hợp file dạng văn File nhị phân: không thay đổi liệu ghi vào thích hợp với việc lưu liệu dạng nhị phân Ghi chuỗi: int fputc(int c, FILE* file); int fputs(const char* s, FILE* file); int fprintf(FILE* file, const char* format, ); Dùng tương tự hàm putc(), puts(), printf() Ghi liệu: int fwrite(const void* buf, int size, int count, FILE* file); Ghi mảng với count phần tử, kích thước phần tử size EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Đọc từ file Đọc chuỗi: int fgetc(FILE* file); int fgets(char* s, int n, FILE* file); int fscanf(FILE* file, const char* format, ); Dùng tương tự hàm getc(), gets(), scanf() hàm fgets() có kiểm tra giới hạn liệu Hàm getc() trả EOF kết thúc file Đọc liệu: int fread(void* buf, int size, int count, FILE* file); Đọc mảng với count phần tử, kích thước phần tử size Kiểm tra kết thúc file hay chưa: int feof(FILE* file); Vì việc đọc/ghi file có sử dụng đệm, nên thường phải dùng hàm fflush() để làm đệm trước chuyển từ ghi sang đọc, từ đọc sang ghi mở file chế độ đọc ghi đồng thời int fflush(FILE* file); EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Các hàm khác đọc/ghi file Đóng file: int fclose(FILE* file); Chuyển trỏ file: void rewind(FILE* file); int fseek(FILE* file, long offs, int org); org = SEEK_CUR: tính từ vị trí org = SEEK_END: tính từ cuối file org = SEEK_SET: giá trị tuyệt đối Ví trí trỏ: long ftell(FILE* file); Kiểm tra xem cuối file chưa: int feof(FILE* file); Xoá file: int remove(const char* path); Đổi tên file: int rename(const char* old, const char* new); EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Ví dụ: hàm copy file int copy_file(const char* src, const char* dst) { FILE *fs = NULL, *fd = NULL; char buf[1024]; int num; if ((fs = fopen(src,"rb")) == NULL) return -1; if ((fd = fopen(dst,"wb")) == NULL) { fclose(fs); return -1; } while(!feof(fs)) { num = fread(buf, sizeof(buf), 1, fs); fwrite(buf, num, 1, fd); } fclose(fs); fclose(fd); return 0; } 10 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội stdin, stdout, stderr Đầu vào/ra chuẩn thực chất biến kiểu FILE* định nghĩa sẵn, nên việc đọc/ghi với hàm printf(…), scanf(…) tương đương với việc dùng fprintf(stdout,…) fscanf(stdin,…) Tương tự với hàm putchar(), puts(), getchar(), gets() thực việc đọc/ghi stdin stdout Định hướng lại đầu vào/ra chuẩn: Ký hiệu command > file command 1> file Đổi stdout file command 2> file Đổi stderr file command >> file command 1>> file Đổi stdout file nối tiếp vào file command 2>> file Đổi stderr file nối tiếp vào file command < file Đổi stdin từ file command1 | command2 11 Ý nghĩa Đổi stdout command1 thành stdin command2 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội stdin, stdout, stderr (tiếp) Một số file đặc biệt Ý nghĩa Tên file Ý nghĩa Tên file &0 nul Bỏ qua &1 stdout prn, lpt1 Máy in &2 stdin stderr Màn hình Ví dụ: Dẫn hướng stdout stderr vào file result.txt C:\>dir *.dat >result.txt 2>&1 Dẫn hướng stdout máy in stderr vào file error.log C:\>stuff >prn 2>error.log Dẫn hướng đầu vào từ file input.txt đầu file output.txt C:\>process output.txt Tạo pipe (output lệnh input lệnh kia) C:\>type source.c | more 12 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Đọc/ghi nhớ Ghi: Đọc: sprintf(char* buffer, const char* format, ); sscanf(const char* buffer, const char* format, ); Dùng tương tự fprintf() fscanf() liệu lưu vào vùng nhớ xác định tham số buffer Ví dụ: char s[50]; sprintf(s, "sin(pi/3) = %.3f", sin(3.14/3)); Kết quả: s chứa chuỗi "sin(pi/3) = 0.866" 13 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Đọc/ghi an tồn 14 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Lỗi tràn đệm Xảy chương trình ghi liệu vào biến nhiều kích thước Ví dụ: copy chuỗi 10 ký tự vào biến dài ký tự char s[5]; strcpy(s1, "0123456789"); Lỗi tràn đệm nguy hiểm gây lỗi khơng dự đốn trước, đặc biệt khiến người sử dụng kiểm sốt máy tính làm Cần kiểm soát chiều dài liệu nhập so với vùng nhớ cấp phát cho biến Các hàm chuẩn C không kiểm tra lỗi tràn đệm sử dụng hàm mở rộng Visual C từ 2005 15 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Các hàm chuỗi nhớ memcpy_s(void* dest, int size, const void* src, int count); memmove_s(void* dest, int size, const void* src, int count); strcpy_s(char* dest, int size, const char* src); strcat_s(char* dest, int size, const char* src); _strlwr_s(char* str, int size); _strupr_s(char* str, int size); 16 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Các hàm đọc liệu gets_s(char* str, int size); scanf_s(const char* format, …); 17 Thêm tham số kiểm tra kích thước biến với chuỗi ký tự int i; float f; char c; char s[10]; scanf_s("%d %f %c %s", &i, &f, &c, 1, s, 10); Tương tự với hàm fscanf_s(), sscanf_s() EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Bài tập 18 Viết chương trình đổi ký tự file sang chữ hoa (tên file từ tham số dịng lệnh) Viết chương trình đếm số từ số dòng file (quy ước từ cách ký tự: cách, tab, xuống dịng) Viết chương trình nối file vào file khác Viết chương trình in dịng thứ 10 file Viết chương trình chèn dòng vào dòng thứ 10 file Viết chương trình nhập liệu cho cấu trúc SinhVien từ bàn phím, sau thử thay đổi stdin stdout từ file xem kết Viết hàm trả kích thước file EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội ... chứa chuỗi "sin(pi/3) = 0.866" 13 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Đọc/ghi an tồn 14 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH... scanf(const char* format, ); EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Xuất nhập từ file Kiểu file: typedef struct { … } FILE; Trình tự thao tác với file: Mở/tạo... trình Đầu vào chuẩn stdin: mặc định bàn phím, coi file ảo đọc, định nghĩa lại file đĩa EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Mở đầu Xuất stdout Xuất