文件IO操做

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s_readbuf[100];
char *ADP_NET_GetModuleVer_SW() {
    FILE *fp = NULL;
    int len;
    fp = fopen("./version", "r");
    if (!fp) {
        printf("fopen error\n");
        return 0;
    }
    fseek(fp, 0, SEEK_END);
    len = ftell(fp);
    rewind(fp);
    fread(s_readbuf, 1, len-1, fp);//len-1 去除換行符
    s_readbuf[len] = '\0';
    fclose(fp);
    fp = NULL;
    return s_readbuf;
}
void main() {
    char *buf = NULL;

    buf = ADP_NET_GetModuleVer_SW();
    printf("file content: %s\n", buf);
}
複製代碼

知識點說明

1、fopen

(1)函數原形緩存

FILE * fopen(const char * path, const char * mode);bash

(2)參數mode 函數

參數mode說明
(3)二進制和文本模式的區別

  • 在Windows系統中,文本模式下,文件以"\r\n"表明換行。若以文本模式打開文件,並用 fputs 等函數寫入換行符"\n"時,函數會自動在"\n"前面加上"\r"。即實際寫入文件的是"\r\n"。
  • 在類 Unix/Linux 系統中文本模式下,文件以"\n"表明換行。因此 Linux 系統中在文本模式和二進制模式下並沒有區別。

(4)返回值ui

文件順利打開後,指向該流的文件指針就會被返回。若是文件打開失敗則返回 NULL,並把錯誤代碼存在 error 中。spa

(5)注意事項指針

  • 在定義文件指針時,要將文件指針指向空;如 FILE *fp = NULL
  • 在文件操做完成後,別忘記fclose,不然會形成內存泄漏和在下次訪問文件時出現問題。
  • 文件關閉後,須要將文件指針指向空,這樣作會防止出現遊離指針,而對整個工程形成沒必要要的麻煩;如:fp = NULL

2、fseek

(1)函數原形code

int fseek(FILE *stream, long offset, int fromwhere);cdn

(2)參數說明blog

第一個參數stream爲文件指針 第二個參數offset爲偏移量,正數表示正向偏移,負數表示負向偏移 第三個參數origin設定從文件的哪裏開始偏移,可能取值爲:SEEK_CUR、 SEEK_END 或 SEEK_SET內存

SEEK_SET: 文件開頭 SEEK_CUR: 當前位置 SEEK_END: 文件結尾

其中SEEK_SET,SEEK_CUR和SEEK_END依次爲0,1和2.

簡言之: fseek(fp,100L,0);把stream指針移動到離文件開頭100字節處; fseek(fp,100L,1);把stream指針移動到離文件當前位置100字節處; fseek(fp,-100L,2);把stream指針退回到離文件結尾100字節處。

(3)返回值

  • 若是執行成功,stream將指向以fromwhere爲基準,偏移offset(指針偏移量)個字節的位置,函數返回0。
  • 若是執行失敗(好比offset超過文件自身大小),則不改變stream指向的位置,函數返回-1,設置error的值,能夠用perror()函數輸出錯誤。

(4)注意事項

  • 文件指針操做文件,會直接覆蓋原先的內容。fread fwrite操做都會對文件指針進行偏移。
  • 實現文件內容中插入字符串,先定位到要插入的文件指針位置,將以後的內容保存在緩存中,插入目標字符串後再把文件緩存的內容添加。
  • 函數 ftell 用於獲得文件位置指針當前位置相對於文件首的偏移字節數。配合fseek使用。會計算換行符的長度
  • 計算完文件長度後,記得rewind(將文件內部的位置指針從新指向一個流(數據流/文件)的開頭)。等價於fseek(stream, 0L, SEEK_SET)。

3、fread

(1)函數原形

size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;

(2)參數說明

buffer 用於接收數據的內存地址 size 要讀的每一個數據項的字節數,單位是字節 count 要讀count個數據項,每一個數據項size個字節. stream 輸入流

(3)返回值

我的理解爲返回數據項數

char *ADP_NET_GetModuleVer_SW() {
    FILE *fp = NULL;
    int len;
    int ret;

    fp = fopen("./version", "r");
    if (!fp) {
        printf("fopen error\n");
        return 0;
    }
    fseek(fp, 0, SEEK_END);
    len = ftell(fp);
    rewind(fp);
    ret = fread(s_readbuf, 1, len-1, fp);//len-1 去除換行符
    printf("len = %d\n", len);
    printf("fread ret = %d\n", ret);
    //fread(s_readbuf, len-1, 1, fp);
    s_readbuf[len] = '\0';
    fclose(fp);
    fp = NULL;
    return s_readbuf;    
}
void main() {
    char *buf = NULL;
    int ret;
    buf = ADP_NET_GetModuleVer_SW();
    printf("file content: %s\n", buf);
}
複製代碼

運行結果:

len = 28
fread ret = 27
file content: plt-ec20-0.01
plt-ec20-0.02
複製代碼

當使用 fread(s_readbuf, 1, len, fp),當len小於fp文件中實際的長度,fread的返回值爲len,當len大於fp文件中實際的長度。fread的返回值爲文件fp實際的長度。

修改成:ret = fread(s_readbuf, 1, 50, fp);
運行結果:
len = 28
fread ret = 28
file content: plt-ec20-0.01
plt-ec20-0.02

修改成:ret = fread(s_readbuf, 1, 5, fp);
運行結果:
len = 28
fread ret = 5
file content: plt-e
複製代碼

當使用 fread(s_readbuf, len, 1, fp),這種語句時,我的理解爲讀取一個數據項,數據項長度爲參數2,當fp文件長度小於len,則說明沒有讀取完整一個數據項,返回值爲0。反之說明已經讀取完整一個數據項,返回值爲1。

修改成:ret = fread(s_readbuf, 50, 1, fp);
運行結果:
len = 28
fread ret = 0
file content: plt-ec20-0.01
plt-ec20-0.02

修改成:ret = fread(s_readbuf, len, 1, fp);
運行結果:
len = 28
fread ret = 1
file content: plt-ec20-0.01
plt-ec20-0.02
複製代碼

四、fwrite

(1)函數原形

size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);

(2)參數說明

  • buffer:是一個指針,對fwrite來講,是要獲取數據的地址;
  • size:要寫入內容的單字節數;
  • count:要進行寫入size字節的數據項的個數;
  • stream:目標文件指針;
  • 返回實際寫入的數據項個數count。

(3)返回值

返回實際寫入的數據塊數目

相關文章
相關標籤/搜索