#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);
}
複製程式碼
知識點說明
一、fopen
(1)函式原形
FILE * fopen(const char * path, const char * mode);
(2)引數mode
(3)二進位制和文字模式的區別- 在Windows系統中,文字模式下,檔案以"\r\n"代表換行。若以文字模式開啟檔案,並用 fputs 等函式寫入換行符"\n"時,函式會自動在"\n"前面加上"\r"。即實際寫入檔案的是"\r\n"。
- 在類 Unix/Linux 系統中文字模式下,檔案以"\n"代表換行。所以 Linux 系統中在文字模式和二進位制模式下並無區別。
(4)返回值
檔案順利開啟後,指向該流的檔案指標就會被返回。如果檔案開啟失敗則返回 NULL,並把錯誤程式碼存在 error 中。
(5)注意事項
- 在定義檔案指標時,要將檔案指標指向空;如 FILE *fp = NULL。
- 在檔案操作完成後,別忘記fclose,否則會造成記憶體洩漏和在下次訪問檔案時出現問題。
- 檔案關閉後,需要將檔案指標指向空,這樣做會防止出現遊離指標,而對整個工程造成不必要的麻煩;如:fp = NULL。
二、fseek
(1)函式原形
int fseek(FILE *stream, long offset, int fromwhere);
(2)引數說明
第一個引數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)。
三、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
複製程式碼
4、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)返回值
返回實際寫入的資料塊數目