文章目錄
- IO(續上)
- 1.標準IO
- 1.標準IO的接口
- 2.流的定位
- 2.文件IO
- 1.概念:
- 2.系統調用和庫函數
- 3.文件IO函數接口
- 習題
IO(續上)
1.標準IO
1.標準IO的接口
-
fwrite
原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream); 功能:向流中寫入ptr指向的nmemb個對象,每個對象size個字節 參數:ptr:指向數據空間的首地址size:寫入的每個對象的大小nmemb:寫入對象的個數stream:文件流指針 返回值:成功返回實際寫入對象的個數失敗返回0
-
fread
原型: size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 功能:從流中讀取nmemb個對象到ptr指向的空間中,每個對象size字節 參數:ptr:存放數據空間的首地址size:讀取對象的字節大小nmemb:讀取對象的個數stream:文件流指針 返回值:成功返回讀到對象的個數失敗或者讀到文件末尾返回0
2.流的定位
-
作用:設置流的偏移量
-
偏移量的設置:
-
fseek
原型:int fseek(FILE *stream,long offset,int whence); 功能:設置流的偏移量的標識 參數:stream:文件流指針offset:偏移量>0 向后偏移<0 向前偏移whence:標識SEEK_SET:文件開頭SEEK_CUR:當前位置SEEK_END:文件末尾 返回值:成功返回0失敗返回-1
-
ftell
原型:long ftell(FILE *stream); 功能:獲得流的偏移量 參數:stream:文件流指針 返回值:成功返回流的偏移量
-
rewind
原型:void rewind(FILE *stream); 功能:將流重新定位到開頭
練習1:從終端輸入一個文件名,獲得文件的長度
#include<stdio.h>int main(void){FILE *fp = NULL;long len = 0;char filename[32] = {0};int cnt = 0;scanf("%s",filename);fp = fopen(filename,"r");if(NULL == fp){perror("fail to fopen");return -1;}fseek(fp,0,SEEK_END);len = ftell(fp);printf("len = %ld\n",len);return 0; }
練習2:從bmp文件中讀取圖片的寬度和高度
#include<stdio.h>int main(void){FILE *fp = NULL;int width = 0;int height = 0;fp = fopen("1.bmp","r");if(NULL == fp){perror("fail to fopen");return -1;}fseek(fp,18,SEEK_SET);fread(&width, 4, 1, fp);fread(&height, 4, 1, fp);printf("width = %d, height = %d\n", width, height);fclose(fp);return 0;}
-
2.文件IO
1.概念:
- 標準IO是有緩存的IO,文件IO沒有緩存,適合于通信,硬件設備操作
- 標準IO是庫函數,文件IO是系統調用
2.系統調用和庫函數
- 系統調用:是Linux內核中的代碼,只能在Linux中使用
- 庫函數:是對系統調用的封裝,可以在不同的操作系統中安裝并使用,庫函數最終還是要調用系統調用完成對應功能
3.文件IO函數接口
-
函數接口
標準IO 文件IO fopen open fclose close fgetc/fputc read/write fgets/fputs fscanf/fprintf fread/fwrite fseek/ftell/rewind lseek
-
文件打開
原型: 功能:打開文件獲得操作文件的文件描述符 參數:pathname:要打開的文件路徑flags:打開文件的標志,必須包含三者之一O_RDONLYO_WRONLYO_RDWRO_CREAT 文件不存在創建O_TRUNC 文件存在截斷為0O_APPEND 追加O_EXCL 文件存在報錯 返回值:成功返回新文件描述符失敗返回-1
- 有三個特殊的文件描述符:標準輸入(0),標準輸出(1),標準錯誤(2)
- 文件描述符特點
- 取未被占用的最小的非負整數
- 文件描述符有上限,到達上限后再打開會報錯誤
-
關閉文件描述符
原型:int close(int fd); 功能: 關閉文件描述符
-
標準IO對應文件IO的打開方式
標準IO | 文件IO |
---|---|
r | O_RDONLY |
r+ | O_RDWR |
w | O_WRONLY |O_CREAT |O_TRUNC , 0664 |
w+ | O_RDWR | O_CREAT | O_TRUNC , 0664 |
a | O_WRONLY |O_APPEND | O_CREAT , 0664 |
a+ | O_RDWR | O_APPEND | O_CREAT , 0664 |
-
文件IO讀寫
-
write
原型:ssize_t write(int fd, const void *buf, size_t count); 功能: 向文件描述符中寫入buf指向的count個字節的數據 參數: fd:文件描述符 buf:要寫入的數據空間首地址 count:要寫入的字節數 返回值: 成功返回實際寫入的字節數 失敗返回-1
-
習題
1.利用fread和fwrite實現圖片的拷貝
代碼實現:
#include<stdio.h>int main(void){FILE *fp = NULL;FILE *fp1 = NULL;char filename[100];char filename1[100];char tmpbuff[4096] = {0};size_t nret = 0;printf("請輸入源圖片名:");scanf("%s",filename);fp = fopen(filename,"r");if(fp == NULL){perror("fail to fopen");return -1;}printf("請輸入目標圖片名:");scanf("%s",filename1);fp1 = fopen(filename1,"w");if(fp1 == NULL){perror("fail to fopen");return -1;}while(1){nret = fread(tmpbuff, 1, sizeof(tmpbuff), fp);if(nret == 0){break;}fwrite(tmpbuff,1,nret,fp1);}fclose(fp);fclose(fp1);return 0;
}
2.統計一個文件中出現最多字符是哪個,并顯示出現了多少次
代碼實現:
#include<stdio.h>
#include<stdlib.h>typedef struct linknode{char data;int count;struct linknode *next;
} node;int main(){FILE *fp = NULL;char filename[100] = {0};char ch;node *head = NULL;node *current = NULL;node *tmp = NULL;int max = 0;printf("請輸入要掃描的文件:");scanf("%s", filename);fp = fopen(filename,"r");if(fp == NULL){printf("無法打開文件!\n");return 1;}while(1){ch = fgetc(fp);if(ch == EOF) {break;}current = head;while(current != NULL){if(current->data == ch){current->count++;break;}current = current->next;}if(current == NULL){tmp = malloc(sizeof(node));if(tmp == NULL){perror("fail to malloc");return -1;}tmp->data = ch;tmp->count = 1;tmp->next = head;head = tmp;}}current = head;while(current != NULL){if(current->count > max){max = current->count;tmp = current;}current = current->next;}printf("出現次數最多的字符為:%c\n出現了%d次\n",tmp->data,tmp->count);while(head != NULL){tmp = head;head = head->next;free(tmp);}fclose(fp);return 0;
}