文章目錄
- 頭檔案:stdio.h
- 檔案打開關閉函數
- 檔案打開(fopen)
- 參數mode可選值
- 案例
- 檔案關閉(fclose)
- 檔案讀寫相關函數
- 總覽
- 字元讀寫函數
- 字元讀寫案例
- 行讀寫函數
- 行讀寫案例
- 塊讀寫函數
- 塊讀寫案例
- 格式化讀寫函數
- 格式化讀寫案例
- 随機讀寫函數
- 随機讀寫案例
- 檔案操作綜合案例
頭檔案:stdio.h
#include <stdio.h>
檔案打開關閉函數
檔案的打開操作表示将給使用者指定的檔案在記憶體配置設定一個
FILE結構區
,并将該結構的指針傳回給使用者程式,以後使用者程式就可用此
FILE指針
來實作對指定檔案的存取操作了。當使用打開函數時,必須給出檔案名、檔案操作方式(讀、寫或讀寫)。
FILE * fopen(const char * filename, const char * mode);
- 功能:打開檔案
-
參數:
:需要打開的檔案名,根據需要加上路徑filename
:打開檔案的權限設定mode
-
傳回值:
成功:檔案指針
失敗:NULL
方式 | 含義 |
| 打開,隻讀,檔案必須已經存在。 |
| 隻寫,如果檔案不存在則建立,如果檔案已存在則把檔案長度截斷(Truncate)為0位元組。再重新寫,也就是替換掉原來的檔案内容檔案指針指到頭。 |
| 隻能在檔案末尾追加資料,如果檔案不存在則建立 |
| 打開一個二進制檔案,隻讀 |
| 打開一個二進制檔案,隻寫 |
| 打開一個二進制檔案,追加 |
| 允許讀和寫,檔案必須已存在 |
| 允許讀和寫,如果檔案不存在則建立,如果檔案已存在則把檔案長度截斷為0位元組再重新寫 。 |
| 允許讀和追加資料,如果檔案不存在則建立 |
| 以讀/寫方式打開一個二進制檔案 |
| 以讀/寫方式建立一個新的二進制檔案 |
| 以讀/寫方式打開一個二進制檔案進行追加 |
檢查fopen的傳回值:
如何函數失敗,它會傳回一個NULL值。如果程式不檢查錯誤,這個NULL指針就會傳給後續的I/O函數。它們将對這個指針執行間接通路,并将失敗
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
FILE *fp = NULL;
// "\\"這樣的路徑形式,隻能在windows使用
// "/"這樣的路徑形式,windows和linux平台下都可用,建議使用這種
// 路徑可以是相對路徑,也可是絕對路徑
fp = fopen("../test", "w");
//fp = fopen("..\\test", "w");
if (fp == NULL) //傳回空,說明打開失敗
{
//perror()是标準出錯列印函數,能列印調用庫函數出錯原因
perror("open");
return;
}
}
int main()
{
test();
return 0;
}
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5yN5QDO1Q2MhR2MlFWZ2Q2NxYzX2ITMxADMxMzLcBTMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLzM3Lc9CX6MHc0RHaiojIsJye.png)
檔案操作完成後,如果程式沒有結束,必須要用
fclose()函數
進行關閉,這是因為對打開的檔案進行寫入時,若檔案緩沖區的空間未被寫入的内容填滿,這些内容不會寫到打開的檔案中。隻有對打開的檔案進行關閉操作時,停留在檔案緩沖區的内容才能寫到該檔案中去,進而使檔案完整。再者一旦關閉了檔案,該檔案對應的
FILE結構
将被釋放,進而使關閉的檔案得到保護,因為這時對該檔案的存取操作将不會進行。檔案的關閉也意味着釋放了該檔案的緩沖區。
int fclose(FILE * stream);
- 功能:關閉先前
打開的檔案。此動作讓緩沖區的資料寫入檔案中,并釋放系統所提供的檔案資源。fopen()
-
:檔案指針stream
-
成功:0
失敗:-1
它表示該函數将關閉FILE指針對應的檔案,并傳回一個整數值。若成功地關閉了檔案,則傳回一個0值,否則傳回一個非0值.
檔案讀寫相關函數
檔案讀寫相關基本函數包括以下幾個方面:
- 按照字元讀寫檔案:fgetc(), fputc()
- 按照行讀寫檔案:fputs(), fgets()
- 按照塊讀寫檔案:fread(), fwirte()
- 按照格式化讀寫檔案:fprintf(), fscanf()
- 按照随機位置讀寫檔案:fseek(), ftell(), rewind()
int fputc(int ch, FILE * stream);
- 功能:将
轉換為ch
後寫入stream指定的檔案中unsigned char
-
:需要寫入檔案的字元ch
stream
-
成功:成功寫入檔案的字元
失敗:傳回-1
int fgetc(FILE * stream);
- 功能:從stream指定的檔案中讀取一個字元
-
stream
- 成功:傳回讀取到的字元
int feof(FILE * stream);
- 功能:檢測是否讀取到了檔案結尾
-
stream
-
非0值:已經到檔案結尾
0:沒有到檔案結尾
将把流指針fp指向的檔案中的一個字元讀出,并賦給ch,當執行
fgetc()函數
時,若當時檔案指針指到檔案尾,即遇到檔案結束标志
EOF(其對應值為-1)
,該函數傳回一個 -1 給ch,在程式中常用檢查該函數傳回值是否為 -1 來判斷是否已讀到檔案尾,進而決定是否繼續。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
//寫檔案
FILE* fp_write = NULL;
//寫方式打開檔案
fp_write = fopen("./mydata.txt", "w+");
if (fp_write == NULL) {
return;
}
char buf[] = "this is a test for pfutc!";
for (int i = 0; i < strlen(buf); i++) {
fputc(buf[i], fp_write);
}
fclose(fp_write);
//讀檔案
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "r");
if (fp_read == NULL) {
return;
}
#if 1
//判斷檔案結尾 注意:多輸出一個空格
while (!feof(fp_read)) {
printf("%c", fgetc(fp_read));
}
#else
char ch;
while ((ch = fgetc(fp_read)) != EOF) {
printf("%c", ch);
}
#endif
}
int main()
{
test();
return 0;
}
輸出結果為:
int fputs(const char * str, FILE * stream);
- 功能:将str所指定的字元串寫入到stream指定的檔案中, 字元串結束符 ‘\0’ 不寫入檔案。
-
:字元串str
stream
char * fgets(char * str, int size, FILE * stream);
- 功能:從stream指定的檔案内讀入字元,儲存到str所指定的記憶體空間,直到出現換行字元、讀到檔案結尾或是已讀了size - 1個字元為止,最後會自動加上字元 ‘\0’ 作為字元串結束。
-
str
:指定最大讀取字元串的長度(size - 1)size
stream
-
成功:成功讀取的字元串
讀到檔案尾或出錯: NULL
往檔案中寫入四行,并讀出輸出。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
//寫檔案
FILE* fp_write = NULL;
//寫方式打開檔案
fp_write = fopen("./mydata.txt", "w+");
if (fp_write == NULL) {
perror("fopen:");
return;
}
char* buf[] = {
"01 倩 this is a test for pfutc!\n",
"02 倩 this is a test for pfutc!\n",
"03 倩 this is a test for pfutc!\n",
"04 倩 this is a test for pfutc!\n",
};
for (int i = 0; i < 4; i++) {
fputs(buf[i], fp_write);
}
fclose(fp_write);
//讀檔案
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "r");
if (fp_read == NULL) {
perror("fopen:");
return;
}
//判斷檔案結尾
while (!feof(fp_read)) {
char temp[1024] = { 0 };
fgets(temp, 1024, fp_read);
printf("%s", temp);
}
fclose(fp_read);
}
int main()
{
test();
return 0;
}
運作結果為:
size_t fwrite(
const void *ptr,
size_t size,
size_t nmemb,
FILE *stream
);
- 功能:以資料塊的方式給檔案寫入内容
-
:準備寫入檔案資料的位址ptr
: size
為 size_t
,此參數指定寫入檔案内容的塊資料大小unsigned int類型
:寫入檔案的塊數,寫入檔案資料總大小為:nmemb
size * nmemb
:已經打開的檔案指針stream
- 成功:實際成功寫入檔案資料的塊數,此值和
nmemb
相等
失敗:0
size_t fread(
void *ptr,
size_t size,
size_t nmemb,
FILE *stream
);
- 功能:以資料塊的方式從檔案中讀取内容
-
:存放讀取出來資料的記憶體空間ptr
size
size_t
,此參數指定讀取檔案内容的塊資料大小unsigned int類型
:讀取檔案的塊數,讀取檔案資料總大小為:nmemb
size * nmemb
stream
- 成功:實際成功讀取到内容的塊數,如果此值比
小,但大于0,說明讀到檔案的結尾。nmemb
建立教師結構體,寫入老師資訊,并從檔案中讀取資訊輸出:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// 老師結構體
typedef struct _TEACHER {
char name[64];
int age;
}Teacher;
void test() {
//寫檔案
FILE* fp_write = NULL;
//寫方式打開檔案
fp_write = fopen("./mydata.txt", "wb");
if (fp_write == NULL) {
perror("fopen:");
return;
}
Teacher teachers[4] = {
{ "倩", 33 },
{ "利", 28 },
{ "Jos", 45},
{ "咪咪", 35}
};
for (int i = 0; i < 4; i++) {
fwrite(&teachers[i], sizeof(Teacher), 1, fp_write);
}
//關閉檔案
fclose(fp_write);
//讀檔案
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "rb");
if (fp_read == NULL) {
perror("fopen:");
return;
}
Teacher temps[4];
fread(&temps, sizeof(Teacher), 4, fp_read);
printf("輸出老師們的資訊:\n");
for (int i = 0; i < 4; i++) {
printf("姓名:%s 年齡:%d\n", temps[i].name, temps[i].age);
}
fclose(fp_read);
}
int main()
{
test();
return 0;
}
int fprintf(FILE * stream, const char * format, ...);
- 功能:根據參數
字元串來轉換并格式化資料,然後将結果輸出到stream指定的檔案中,指定出現字元串結束符format
為止。'\0'
-
:已經打開的檔案stream
:字元串格式,用法和format
一樣printf()
- 成功:實際寫入檔案的字元個數
int fscanf(FILE * stream, const char * format, ...);
- 功能:從
指定的檔案讀取字元串,并根據參數stream
字元串來轉換并格式化資料。format
-
stream
format
scanf()
-
成功:實際從檔案中讀取的字元個數
失敗: - 1
注意:fscanf遇到空格和換行時結束。
寫入一行帶空格的字元串,讀取輸出:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
//寫檔案
FILE* fp_write = NULL;
//寫方式打開檔案
fp_write = fopen("./mydata.txt", "w");
if (fp_write == NULL) {
perror("fopen:");
return;
}
fprintf(fp_write, "he llo wor ld :%d!", 99999);
//關閉檔案
fclose(fp_write);
//讀檔案
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "rb");
if (fp_read == NULL) {
perror("fopen:");
return;
}
char temps[1024] = { 0 };
while (!feof(fp_read)) {
fscanf(fp_read, "%s", temps);
printf("%s", temps);
}
fclose(fp_read);
}
int main()
{
test();
return 0;
}
注意:這裡的随機讀寫,不是系統随機位置就真随意讀寫了,是你要指定的随意位置進行讀寫
int fseek(FILE *stream, long offset, int whence);
- 功能:移動檔案流(檔案光标)的讀寫位置。
-
:已經打開的檔案指針stream
:根據offset
來移動的位移數(偏移量),可以是正數,也可以負數,如果正數,則相對于whence
往右移動,如果是負數,則相對于whence
往左移動。如果向前移動的位元組數超過了檔案開頭則出錯傳回,如果向後移動的位元組數超過了 檔案末尾,再次寫入時将增大檔案尺寸。whence
:其取值如下:whence
-
:從檔案開頭移動offset個位元組SEEK_SET
-
:從目前位置移動offset個位元組SEEK_CUR
-
:從檔案末尾移動offset個位元組SEEK_END
long ftell(FILE *stream);
- 功能:擷取檔案流(檔案光标)的讀寫位置。
-
stream
- 成功:目前檔案流(檔案光标)的讀寫位置
void rewind(FILE *stream);
- 功能:把檔案流(檔案光标)的讀寫位置移動到檔案開頭。
-
stream
- 無傳回值
随機位置讀取不同老師:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct _TEACHER {
char name[64];
int age;
}Teacher;
void test() {
//寫檔案
FILE* fp_write = NULL;
//寫方式打開檔案
fp_write = fopen("./mydata.txt", "wb");
if (fp_write == NULL) {
perror("fopen:");
return;
}
Teacher teachers[4] = {
{ "1倩", 33 },
{ "2利", 28 },
{ "3Jos", 45},
{ "4咪咪", 35}
};
for (int i = 0; i < 4; i++) {
fwrite(&teachers[i], sizeof(Teacher), 1, fp_write);
}
//關閉檔案
fclose(fp_write);
//讀檔案
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "rb");
if (fp_read == NULL) {
perror("fopen:");
return;
}
Teacher temp;
// 從檔案開頭移動:讀取第三個
fseek(fp_read, sizeof(Teacher) * 2, SEEK_SET);
fread(&temp, sizeof(Teacher), 1, fp_read);
printf("Name:%s Age:%d\n", temp.name, temp.age);
memset(&temp, 0, sizeof(Teacher));
// 從檔案末尾移動:讀取第四個
fseek(fp_read, -(int)sizeof(Teacher), SEEK_END);
fread(&temp, sizeof(Teacher), 1, fp_read);
printf("Name:%s Age:%d\n", temp.name, temp.age);
// 重新從檔案開頭讀取
rewind(fp_read);
fread(&temp, sizeof(Teacher), 1, fp_read);
printf("Name:%s Age:%d\n", temp.name, temp.age);
fclose(fp_read);
}
int main()
{
test();
return 0;
}
檔案操作綜合案例