日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C/C++学习之路_九:文件操作

發布時間:2024/4/11 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C/C++学习之路_九:文件操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C/C++學習之路_九:文件操作


目錄

  • 概述
  • 文件的順序讀寫
  • 文件的隨機讀寫
  • windows和linux文本
  • 獲取文件狀態
  • 刪除文件、重命名文件
  • 文件緩沖區

  • 1. 概述

    1. 磁盤文件和設備文件

  • 磁盤文件:指一組相關數據的有序集合,通常存儲在外部介質(如磁盤)上,使用時才調入內存。
  • 設備文件:在操作系統中把每一個與主機相連的輸入、輸出設備看作是一個文件,把它們的輸入、輸出等同于對磁盤文件的讀和寫。
  • 2. 磁盤文件的分類

  • 計算機的存儲在物理上是二進制的,所以物理上所有的磁盤文件本質上都是一樣的:以字節為單位進行順序存儲。
  • 從用戶或者操作系統使用的角度(邏輯上)把文件分為:
  • 文本文件:基于字符編碼的文件
  • 二進制文件:基于值編碼的文件
  • 3. 文本文件和二進制文件

  • 文本文件

  • 基于字符編碼,常見編碼有ASCII、UNICODE等
  • 一般可以使用文本編輯器直接打開
  • 數5678的以ASCII存儲形式(ASCII碼)為:00110101 00110110 00110111 00111000
  • 二進制文件

  • 基于值編碼,自己根據具體應用,指定某個值是什么意思
  • 把內存中的數據按其在內存中的存儲形式原樣輸出到磁盤上
  • 數5678的存儲形式(二進制碼)為:
  • 00010110 00101110

  • 2 文件的打開和關閉

    1. 文件指針

  • 在C語言中用一個指針變量指向一個文件,這個指針稱為文件指針。
  • typedef struct {short level; //緩沖區"滿"或者"空"的程度 unsigned flags; //文件狀態標志 char fd; //文件描述符unsigned char hold; //如無緩沖區不讀取字符short bsize; //緩沖區的大小unsigned char *buffer;//數據緩沖區的位置 unsigned ar; //指針,當前的指向 unsigned istemp; //臨時文件,指示器short token; //用于有效性的檢查 }FILE;
  • FILE是系統使用typedef定義出來的有關文件信息的一種結構體類型,結構中含有文件名、文件狀態和文件當前位置等信息。

  • 聲明FILE結構體類型的信息包含在頭文件“stdio.h”中,一般設置一個指向FILE類型變量的指針變量,然后通過它來引用這些FILE類型變量。通過文件指針就可對它所指的文件進行各種操作。

  • C語言中有三個特殊的文件指針由系統默認打開,用戶無需定義即可直接使用:

  • stdin: 標準輸入,默認為當前終端(鍵盤),我們使用的scanf、getchar函數默認從此終端獲得數據。
  • stdout:標準輸出,默認為當前終端(屏幕),我們使用的printf、puts函數默認輸出信息到此終端。
  • stderr:標準出錯,默認為當前終端(屏幕),我們使用的perror函數默認輸出信息到此終端。
  • 2. 文件的打開

  • 任何文件使用之前必須打開:
  • #include <stdio.h> FILE * fopen(const char * filename, const char * mode); 功能:打開文件 參數:filename:需要打開的文件名,根據需要加上路徑mode:打開文件的模式設置 返回值:成功:文件指針失敗:NULL
  • 第一個參數的幾種形式:
  • FILE *fp_passwd = NULL;//相對路徑://打開當前目錄passdw文件:源文件(源程序)所在目錄FILE *fp_passwd = fopen("passwd.txt", "r");//打開當前目錄(test)下passwd.txt文件fp_passwd = fopen("./test/passwd.txt", "r");//打開當前目錄上一級目錄(相對當前目錄)passwd.txt文件fp_passwd = fopen("../passwd.txt", "r");//絕對路徑, 打開C盤test目錄下一個叫passwd.txt文件fp_passwd = fopen("c:/test/passwd.txt","r");
  • 第二個參數的幾種形式(打開文件的方式):
  • 打開模式含義
    r或rb以只讀方式打開一個文本文件(不創建文件,若文件不存在則報錯)
    w或wb以寫方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件)
    a或ab以追加方式打開文件,在末尾添加內容,若文件不存在則創建文件
    r+或rb+以可讀、可寫的方式打開文件(不創建新文件)
    w+或wb+以可讀、可寫的方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件)
    a+或ab+以添加方式打開文件,打開文件并在末尾更改文件,若文件不存在則創建文件
  • 注意:
  • b是二進制模式的意思,b只是在Windows有效,在Linux用r和rb的結果是一樣的
  • Unix和Linux下所有的文本文件行都是\n結尾,而Windows所有的文本文件行都是\r\n結尾
  • 在Windows平臺下,以“文本”方式打開文件,不加b:
  • 當讀取文件的時候,系統會將所有的 “\r\n” 轉換成 “\n”
  • 當寫入文件的時候,系統會將 “\n” 轉換成 “\r\n” 寫入
  • 以"二進制"方式打開文件,則讀寫都不會進行這樣的轉換
  • 在Unix/Linux平臺下,“文本”與“二進制”模式沒有區別,"\r\n" 作為兩個字符原樣輸入輸出
  • int main() {FILE *fp = NULL;fp = fopen("./test.txt", "w");if (fp == NULL) {perror("open fail!");return -1;}return 0; }

    3. 文件的關閉

  • 任何文件在使用后應該關閉:
  • 打開的文件會占用內存資源,如果總是打開不關閉,會消耗很多內存
  • 一個進程同時打開的文件數是有限制的,超過最大同時打開文件數,再次調用fopen打開文件會失敗
  • 如果沒有明確的調用fclose關閉打開的文件,那么程序在退出的時候,操作系統會統一關閉。
  • #include <stdio.h> int fclose(FILE * stream); 功能:關閉先前fopen()打開的文件。此動作讓緩沖區的數據寫入文件中,并釋放系統所提供的文件資源。 參數:stream:文件指針 返回值:成功:0失敗:-1FILE * fp = NULL;fp = fopen("abc.txt", "r");fclose(fp);

    2. 文件的順序讀寫

    1. 按照字符讀寫文件

    1. 寫文件

    #include <stdio.h> int fputc(int ch, FILE * stream); 功能:將ch轉換為unsigned char后寫入stream指定的文件中 參數:ch:需要寫入文件的字符stream:文件指針 返回值:成功:成功寫入文件的字符失敗:返回-1 int main() {FILE *fp = NULL;fp = fopen("./test.txt", "w");if (fp == NULL) {perror("open fail!");return -1;}char buf[] = "this is a test for fputc";int i = 0;int n = strlen(buf);for (i = 0; i < n; i++) {//往文件fp寫入字符buf[i]int ch = fputc(buf[i], fp);printf("ch = %c\n", ch);}fclose(fp);return 0; }

    2. 文件結尾

  • 在C語言中,EOF表示文件結束符(end of file)。在while循環中以EOF作為文件結束標志,這種以EOF作為文件結束標志的文件,必須是文本文件。
  • 在文本文件中,數據都是以字符的ASCII代碼值的形式存放。我們知道,ASCII代碼值的范圍是0~127,不可能出現-1,因此可以用EOF作為文件結束標志。
  • #define EOF (-1)
  • 當把數據以二進制形式存放到文件中時,就會有-1值的出現,因此不能采用EOF作為二進制文件的結束標志。
  • 為解決這一個問題,ANSI C提供一個feof函數,用來判斷文件是否結束。feof函數既可用以判斷二進制文件又可用以判斷文本文件。
  • #include <stdio.h> int feof(FILE * stream); 功能:檢測是否讀取到了文件結尾。判斷的是最后一次“讀操作的內容”,不是當前位置內容(上一個內容)。 參數:stream:文件指針 返回值:非0值:已經到文件結尾0:沒有到文件結尾

    3. 讀文件

    #include <stdio.h> int fgetc(FILE * stream); 功能:從stream指定的文件中讀取一個字符 參數:stream:文件指針 返回值:成功:返回讀取到的字符失敗:-1 char ch;/*while ((ch = fgetc(fp))!=EOF){printf("%c",ch);}printf("\n");*/while (!feof(fp)){ch = fgetc(fp);printf("%c",ch);}printf("\n");

    2. 按照行讀寫文件

    1. 寫文件

    #include <stdio.h> int fputs(const char * str, FILE * stream); 功能:將str所指定的字符串寫入到stream指定的文件中,字符串結束符 '\0' 不寫入文件。 參數:str:字符串stream:文件指針 返回值:成功:0失敗:-1 char *buf[] = {"123456\n", "bbbbbbbbbb\n", "ccccccccccc\n"};int i = 0;int n = 3;for (i = 0; i < n; i++) {int len = fputs(buf[i], fp);printf("len = %d\n", len);}

    2. 讀文件

    #include <stdio.h> char * fgets(char * str, int size, FILE * stream); 功能:從stream指定的文件內讀入字符,保存到str所指定的內存空間,直到出現換行字符、讀到文件結尾或是已讀了size - 1個字符為止,最后會自動加上字符 '\0' 作為字符串結束。 參數:str:字符串size:指定最大讀取字符串的長度(size - 1)stream:文件指針 返回值:成功:成功讀取的字符串讀到文件尾或出錯: NULL char buf[100] = {0};while (!feof(fp)) {memset(buf, 0, sizeof(buf));char *p = fgets(buf, sizeof(buf), fp);if (p != NULL) {printf("buf=%s", buf);}}

    3. 按照格式化文件

    1. 寫文件

    #include <stdio.h> int fprintf(FILE * stream, const char * format, ...); 功能:根據參數format字符串來轉換并格式化數據,然后將結果輸出到stream指定的文件中,指定出現字符串結束符 '\0' 為止。 參數:stream:已經打開的文件format:字符串格式,用法和printf()一樣 返回值:成功:實際寫入文件的字符個數失敗:-1 fprintf(fp, "%d %d %d\n", 1, 2, 3);

    2. 讀文件

    #include <stdio.h> int fscanf(FILE * stream, const char * format, ...); 功能:從stream指定的文件讀取字符串,并根據參數format字符串來轉換并格式化數據。 參數:stream:已經打開的文件format:字符串格式,用法和scanf()一樣 返回值:成功:參數數目,成功轉換的值的個數失敗: - 1 int a = 0;int b = 0;int c = 0;fscanf(fp, "%d %d %d\n", &a, &b, &c);printf("a = %d, b = %d, c = %d\n", a, b, c);

    4. 按照塊讀寫文件

    1. 寫文件

    #include <stdio.h> size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 功能:以數據塊的方式給文件寫入內容 參數:ptr:準備寫入文件數據的地址size: size_tunsigned int類型,此參數指定寫入文件內容的塊數據大小nmemb:寫入文件的塊數,寫入文件數據總大小為:size * nmembstream:已經打開的文件指針 返回值:成功:實際成功寫入文件數據的塊數目,此值和 nmemb 相等失敗:0 typedef struct Stu {char name[50];int id; } Stu;int Write() {FILE *fp = NULL;fp = fopen("./test.txt", "w");if (fp == NULL) {perror("open fail!");return -1;}Stu s[3];for (int i = 0; i < 3; i++) {sprintf(s[i].name, "stu%d%d%d", i, i, i);s[i].id = i + 1;}int ret = fwrite(s, sizeof(Stu), 3, fp);printf("ret=%d\n", ret);fclose(fp);return 0; }

    2. 讀文件

    #include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 功能:以數據塊的方式從文件中讀取內容 參數:ptr:存放讀取出來數據的內存空間size: size_tunsigned int類型,此參數指定讀取文件內容的塊數據大小nmemb:讀取文件的塊數,讀取文件數據總大小為:size * nmembstream:已經打開的文件指針 返回值:成功:實際成功讀取到內容的塊數,如果此值比nmemb小,但大于0,說明讀到文件的結尾。失敗:0 Stu s[3];int ret = fread(s, sizeof(Stu), 3, fp);printf("ret=%d\n", ret);for (int i = 0; i < 3; i++) {printf("s = %s, %d", s[i].name, s[i].id);}

    4. 文件的隨機讀寫

    #include <stdio.h> int fseek(FILE *stream, long offset, int whence); 功能:移動文件流(文件光標)的讀寫位置。 參數:stream:已經打開的文件指針offset:根據whence來移動的位移數(偏移量),可以是正數,也可以負數,如果正數,則相對于whence往右移動,如果是負數,則相對于whence往左移動。如果向前移動的字節數超過了文件開頭則出錯返回,如果向后移動的字節數超過了文件末尾,再次寫入時將增大文件尺寸。whence:其取值如下:SEEK_SET:從文件開頭移動offset個字節SEEK_CUR:從當前位置移動offset個字節SEEK_END:從文件末尾移動offset個字節 返回值:成功:0失敗:-1#include <stdio.h> long ftell(FILE *stream); 功能:獲取文件流(文件光標)的讀寫位置。 參數:stream:已經打開的文件指針 返回值:成功:當前文件流(文件光標)的讀寫位置失敗:-1#include <stdio.h> void rewind(FILE *stream); 功能:把文件流(文件光標)的讀寫位置移動到文件開頭。 參數:stream:已經打開的文件指針 返回值:無返回值 FILE *fp = NULL;fp = fopen("./test.txt", "r");if (fp == NULL) {perror("open fail!");return -1;}Stu s[3];Stu tmp;int ret = 0;fseek(fp, 2 * sizeof(Stu), SEEK_SET);ret = fread(&tmp, sizeof(Stu), 1, fp);if (ret == 1) {printf("[tmp]%s, %d\n", tmp.name, tmp.id);}rewind(fp);ret = fread(s, sizeof(Stu), 3, fp);printf("ret = %d\n", ret);int i = 0;for (i = 0; i < 3; i++) {printf("s === %s, %d\n", s[i].name, s[i].id);}

    5. windows和linux文本

  • b是二進制模式的意思,b只是在Windows有效,在Linux用r和rb的結果是一樣的
  • Unix和Linux下所有的文本文件行都是\n結尾,而Windows所有的文本文件行都是\r\n結尾
  • 在Windows平臺下,以“文本”方式打開文件,不加b:
  • 當讀取文件的時候,系統會將所有的 “\r\n” 轉換成 “\n”
  • 當寫入文件的時候,系統會將 “\n” 轉換成 “\r\n” 寫入
  • 以"二進制"方式打開文件,則讀\寫都不會進行這樣的轉換
  • 在Unix/Linux平臺下,“文本”與“二進制”模式沒有區別,"\r\n" 作為兩個字符原樣輸入輸出
  • 判斷文本文件是Linux格式還是Windows格式:
  • int main(int argc, char **args) {if (argc < 2)return 0;FILE *p = fopen(args[1], "rb");if (!p)return 0;char a[1024] = {0};fgets(a, sizeof(a), p);int len = 0;while (a[len]) {if (a[len] == '\n') {if (a[len - 1] == '\r') {printf("windows file\n");} else {printf("linux file\n");}}len++;}fclose(p);return 0; }

    6. 獲取文件狀態

    #include <sys/types.h> #include <sys/stat.h> int stat(const char *path, struct stat *buf); 功能:獲取文件狀態信息 參數: path:文件名 buf:保存文件信息的結構體 返回值: 成功:0 失敗-1struct stat {dev_t st_dev; //文件的設備編號ino_t st_ino; //節點mode_t st_mode; //文件的類型和存取的權限nlink_t st_nlink; //連到該文件的硬連接數目,剛建立的文件值為1uid_t st_uid; //用戶IDgid_t st_gid; //組IDdev_t st_rdev; //(設備類型)若此文件為設備文件,則為其設備編號off_t st_size; //文件字節數(文件大小)unsigned long st_blksize; //塊大小(文件系統的I/O 緩沖區大小)unsigned long st_blocks; //塊數time_t st_atime; //最后一次訪問時間time_t st_mtime; //最后一次修改時間time_t st_ctime; //最后一次改變時間(指屬性) };

    7. 刪除文件、重命名文件

    #include <stdio.h> int remove(const char *pathname); 功能:刪除文件 參數:pathname:文件名 返回值:成功:0失敗:-1#include <stdio.h> int rename(const char *oldpath, const char *newpath); 功能:把oldpath的文件名改為newpath 參數: oldpath:舊文件名 newpath:新文件名 返回值: 成功:0 失敗: - 1

    8. 文件緩沖區

    1. 文件緩沖區

  • ANSI C標準采用“緩沖文件系統”處理數據文件。
  • 所謂緩沖文件系統是指系統自動地在內存區為程序中每一個正在使用的文件開辟一個文件緩沖區從內存向磁盤輸出數據必須先送到內存中的緩沖區,裝滿緩沖區后才一起送到磁盤去。
  • 如果從磁盤向計算機讀入數據,則一次從磁盤文件將一批數據輸入到內存緩沖區(充滿緩沖區),然后再從緩沖區逐個地將數據送到程序數據區(給程序變量) 。
  • 2. 磁盤文件的存取

  • 磁盤文件,一般保存在硬盤、U盤等掉電不丟失的磁盤設備中,在需要時調入內存
  • 在內存中對文件進行編輯處理后,保存到磁盤中
  • 程序與磁盤之間交互,不是立即完成,系統或程序可根據需要設置緩沖區,以提高存取效率
  • 3. 更新緩沖區

    #include <stdio.h> int fflush(FILE *stream); 功能:更新緩沖區,讓緩沖區的數據立馬寫到文件中。 參數: stream:文件指針 返回值: 成功:0 失敗:-1

    總結

    以上是生活随笔為你收集整理的C/C++学习之路_九:文件操作的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。