怎么找人做動漫視頻網(wǎng)站seo關(guān)鍵詞排名優(yōu)化的方法
目錄
文件
文件名:
標(biāo)準(zhǔn)流
文件指針
文件的打開和關(guān)閉
文件的順序讀寫:
使用部分
文件的打開和關(guān)閉
文件
文件分兩種,第一種是程序文件,后一種是數(shù)據(jù)文件。
程序文件:包括源程序文件(后綴為.c),目標(biāo)文件(windows環(huán)境后綴為.obj)可執(zhí)行程序(windows環(huán)境后綴為.exe)。
數(shù)據(jù)文件:文件的內(nèi)同 不一定是程序,而是程序員運行時讀寫的數(shù)據(jù),比如程序運行需要從中讀取數(shù)據(jù)的文件,或者輸出的文件。
文件名:
文件名包含三部分:文件路徑+文件名主干+文件后綴
例:c:\code\test.txt
進行文件操作時需要用到流
"流"(stream)通常用于描述數(shù)據(jù)的傳輸或處理。流可以是輸入流(input stream)或輸出流(output stream),它們分別用于從外部源讀取數(shù)據(jù)或?qū)?shù)據(jù)寫入外部目標(biāo)。
輸入流:輸入流用于從外部源(比如文件、鍵盤、網(wǎng)絡(luò)等)讀取數(shù)據(jù)到程序中。在C語言中,你可以使用標(biāo)準(zhǔn)輸入流(stdin)來接收用戶輸入,也可以使用文件輸入流來讀取文件中的數(shù)據(jù)。
輸出流:輸出流用于將程序中的數(shù)據(jù)寫入外部目標(biāo)(比如文件、屏幕、網(wǎng)絡(luò)等)。在C語言中,你可以使用標(biāo)準(zhǔn)輸出流(stdout)來輸出到屏幕上,也可以使用文件輸出流將數(shù)據(jù)寫入文件。
標(biāo)準(zhǔn)流
stdin-標(biāo)準(zhǔn)輸入流,可以將數(shù)據(jù)寫入一個文本文件,并將該文件重定向到程序的標(biāo)準(zhǔn)輸入。
stdout-標(biāo)準(zhǔn)輸出流,程序的輸出重定向到文件或其他位置,可以使用標(biāo)準(zhǔn)輸出(stdout)重定向。
stderr-標(biāo)準(zhǔn)錯誤流,大多數(shù)環(huán)境中輸出到顯示器上面。
標(biāo)準(zhǔn)流的類型是FILE*,通常稱為文件指針。
文件指針
緩沖文件系統(tǒng)中,關(guān)鍵的概念是“文件類型指針”簡稱“文件指針”
每個被使用的文件都在內(nèi)存中開辟了一個相應(yīng)的文件信息區(qū)。這些信息保存在結(jié)構(gòu)體變量中,該結(jié)構(gòu)體由系統(tǒng)聲明,取名FILE
結(jié)構(gòu)體原型:
typedef struct _iobuf {
? ? char *_ptr;
? ? int _cnt;
? ? char *_base;
? ? int _flag;
? ? int _file;
? ? int _charbuf;
? ? int _bufsiz;
? ? char *_tmpfname;
} FILE;
文件的讀寫
文件讀寫應(yīng)先打開后關(guān)閉
ANSIC規(guī)定使用fopen函數(shù)打開文件,fclose來關(guān)閉文件。
//打開文件
FILE * fopen(const char * filename, const char * mode);
//關(guān)閉文件
int fclose(FILE * stream);
文件的使用方式
文件的順序讀寫:
fgetc和fputc
fgetc
是C標(biāo)準(zhǔn)庫中用于從文件中讀取一個字符的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
int fgetc(FILE *stream);
stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要讀取字符的文件流。
fgetc
函數(shù)的作用是從指定的文件流中讀取一個字符,并將該字符作為無符號字符返回。如果到達文件末尾或者發(fā)生錯誤,它會返回 EOF(End Of File)。
fputc
是C標(biāo)準(zhǔn)庫中用于向文件中寫入一個字符的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
int fputc(int character, FILE *stream);
character
:要寫入到文件的字符。stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要寫入字符的文件流。
fputc
函數(shù)的作用是向指定的文件流中寫入一個字符。它會將指定的字符寫入到文件中,并返回寫入的字符。如果寫入成功,則返回寫入的字符;如果發(fā)生錯誤,返回 EOF
。
fgets和fputs
fgets
是C標(biāo)準(zhǔn)庫中用于從文件流中讀取一行數(shù)據(jù)的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
char *fgets(char *str, int num, FILE *stream);
str
:指向一個字符數(shù)組的指針,用于存儲讀取的字符串?dāng)?shù)據(jù)。num
:要讀取的最大字符數(shù)(包括空字符)。stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要讀取數(shù)據(jù)的文件流。
fgets
函數(shù)會從指定的文件流中讀取一行數(shù)據(jù)(包括換行符),并將其存儲到指定的字符數(shù)組中。它會一直讀取直到遇到換行符 \n
、文件結(jié)束符 EOF
或者讀取了 num-1
個字符為止,并在最后添加一個 null 字符 \0
作為字符串的結(jié)尾。
fputs
是C標(biāo)準(zhǔn)庫中用于向文件中寫入字符串的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
int fputs(const char *str, FILE *stream);
str
:要寫入到文件的字符串。stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要寫入字符串的文件流。
fputs
函數(shù)的作用是向指定的文件流中寫入一個以 null 結(jié)尾的字符串。它會將指定的字符串寫入到文件中,并返回非負(fù)值(非錯誤);如果發(fā)生錯誤,返回 EOF
。
fscanf和fprintf
fscanf
是C標(biāo)準(zhǔn)庫中用于從文件中讀取格式化輸入的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
int fscanf(FILE *stream, const char *format, ...);
stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要讀取數(shù)據(jù)的文件流。format
:格式化字符串,指定了要讀取的數(shù)據(jù)類型和格式。
fscanf
函數(shù)根據(jù)指定的格式字符串從文件流中讀取數(shù)據(jù),并根據(jù)格式進行解析和存儲。它將讀取的數(shù)據(jù)轉(zhuǎn)換為相應(yīng)的數(shù)據(jù)類型,并按照格式字符串的指示將數(shù)據(jù)存儲到相應(yīng)的變量中。
fprintf
是C標(biāo)準(zhǔn)庫中用于將格式化數(shù)據(jù)輸出到文件的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
int fprintf(FILE *stream, const char *format, ...);
stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要輸出數(shù)據(jù)的文件流。format
:格式化字符串,指定了要輸出的數(shù)據(jù)類型和格式。
fprintf
函數(shù)根據(jù)指定的格式字符串將數(shù)據(jù)格式化后輸出到指定的文件流中。它類似于 printf
函數(shù),但是可以將輸出重定向到文件而不是標(biāo)準(zhǔn)輸出。
fread和fwrite
fread
是C標(biāo)準(zhǔn)庫中用于從文件中讀取數(shù)據(jù)的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr
:指向存儲讀取數(shù)據(jù)的內(nèi)存塊的指針。size
:要讀取的每個數(shù)據(jù)項的字節(jié)數(shù)。nmemb
:要讀取的數(shù)據(jù)項的數(shù)量。stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要讀取數(shù)據(jù)的文件流。
fread
函數(shù)從文件流中讀取數(shù)據(jù),并將數(shù)據(jù)存儲到指定的內(nèi)存塊中。它會返回實際讀取的數(shù)據(jù)項數(shù)量,通常用于讀取二進制數(shù)據(jù)。
fwrite
是 C 標(biāo)準(zhǔn)庫中用于將數(shù)據(jù)寫入文件的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr
:指向要寫入文件的數(shù)據(jù)塊的指針。size
:每個數(shù)據(jù)項的大小(字節(jié)數(shù))。nmemb
:要寫入的數(shù)據(jù)項的數(shù)量。stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要寫入數(shù)據(jù)的文件流。
fwrite
函數(shù)將指定數(shù)量的數(shù)據(jù)項從內(nèi)存中寫入到文件中。它通常用于寫入二進制數(shù)據(jù)到文件。
使用部分
文件的打開和關(guān)閉
以下是打開文件和關(guān)閉文件的操作
#include <stdio.h>int main()
{FILE* pf = fopen("data.txt", "w");//創(chuàng)建文件 打開文件if (pf == NULL){perror("fopen");return 1;}//寫文件//....//關(guān)閉文件fclose(pf);pf = NULL;return 0;
}
這樣就創(chuàng)建了data.txt文件
在我這里,D:\clone倉庫\test.c\test_3_26表示當(dāng)前目錄
.表示當(dāng)前目錄
..表示上一目錄
fputc和fgetc的使用
使用fputc寫入26個小寫字母
int main()
{FILE* pf = fopen("data.txt", "w");if (pf == NULL){perror("fopen");return 1;}int i = 0;for (i = 0; i < 26; i++){fputc('a' + i, pf);}fclose(pf);pf = NULL;return 0;
}
使用fgetc讀取data.txt的內(nèi)容
fputc和fgetc的讀寫都有一個共同的特點,就是光標(biāo)會隨著讀寫依次往后跳
使用fgetc函數(shù)讀取data1.txt中的內(nèi)容,再使用fputc函數(shù)輸出到data.txt中
這里我先創(chuàng)建好了data1.txt并輸入了內(nèi)容abcdefghi。
另外需要注意的是當(dāng)data2.txt開辟失敗時,進行判斷后,應(yīng)先關(guān)閉文件data1.txt后置空。
int main()
{//D:\clone倉庫\test.c\test_3_26表示當(dāng)前目錄//.表示當(dāng)前目錄//..表示上一目錄FILE* pf1 = fopen("data1.txt", "r");//創(chuàng)建文件 打開文件if (pf1 == NULL){perror("fopen");return 1;}FILE* pf2 = fopen("data2.txt", "w");if (pf2 == NULL){fclose(pf1);pf1 = NULL;perror("fopen->data2.txt");return 1;}//寫文件int ch = 0;while ((ch = fgetc(pf1)) != EOF){fputc(ch, pf2);}//關(guān)閉文件fclose(pf1);fclose(pf2);pf1 = NULL;pf2 = NULL;return 0;
}
fgets和fputs的使用
fputs一次寫入一行
int main()
{FILE* pf = fopen("data.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputs("abcdefg\n", pf);fputs("abcdefg\n", pf);fputs("abcdefg\n", pf);fclose(pf);pf = NULL;return 0;
}
fgets注意有三個參數(shù),其中的num參數(shù)是最多讀取多少個的意思,最多讀取num-1個字符。
第一個參數(shù)是數(shù)組第二參數(shù)是num,第三個參數(shù)是文件指針,是把文件里的字符讀取到數(shù)組中
這里data.txt是一堆字母,num是10,但一共讀取了9個字符。
fscanf和fprintf的使用
讀取帶有格式化的字符
struct stu
{char neme[30];int age;double score;
};int main()
{struct stu s = { "zhangsan", 29, 99.5 };FILE* pf = fopen("data.txt", "w");if (pf == NULL){perror("fopen");return 1;}//寫文件fprintf(pf, "%s %d %.1lf", s.neme, s.age, s.score);fclose(pf);pf = NULL;return 0;
}
注意使用fscanf和scanf一樣要&(取地址)
這里創(chuàng)建了一個未初始化的s使用fscanf函數(shù)讀取data.txt的內(nèi)容讀入s中,后用fprintf打印再屏幕上。
fread和fwrite的使用
二進制的讀寫
fwrite四個參數(shù),第一個是要寫數(shù)據(jù)的起始地址,第二個是一個元素的大小,第三個是寫入的個數(shù),第四個是流
再文件出現(xiàn)了亂碼,這就是二進制翻譯出的字符,不能識別
struct stu
{char neme[30];int age;double score;
};int main()
{struct stu s = { "zhangsan", 19, 99.5 };FILE* pf = fopen("data.txt", "wb");//二進制讀寫if (pf == NULL){perror("fopen");return 1;}//寫文件fwrite(&s, sizeof(s), 1, pf);//寫到pf中fclose(pf);pf = NULL;return 0;
}
fread可以識別二進制的代碼
struct stu
{char neme[30];int age;double score;
}s;int main()
{//struct stu s = { "zhangsan", 19, 99.5 };FILE* pf = fopen("data.txt", "rb");//二進制讀寫if (pf == NULL){perror("fopen");return 1;}//fwrite(&s, sizeof(s), 1, pf);//讀文件fread(&s, sizeof(s), 1, pf);//寫到pf中printf("%s %d %.1lf", s.neme, s.age, s.score);fclose(pf);pf = NULL;return 0;
}
比較一組函數(shù)
scanf/fscanf/sscanf
printf/fprintf/sprintf
前面已經(jīng)介紹了fscanf和fprintf了,但這里還有一組函數(shù),即sscanf和sprintf
scanf——針對標(biāo)準(zhǔn)輸入流的格式化輸入函數(shù)
printf——針對標(biāo)準(zhǔn)輸出流的格式化輸出函數(shù)
fscanf——針對所有輸出流的的格式化輸入函數(shù)
fprintf——針對所有輸入流的格式化輸出函數(shù)
sscanf
sscanf是從一個字符串中讀取一個格式化的數(shù)據(jù)
sprintf
sprintf和printf都是使用格式化的數(shù)據(jù),最大的差別在于sprintf多了一個參數(shù)
這個參數(shù)的作用是將格式化的數(shù)據(jù)轉(zhuǎn)換成字符串。
使用
把一個結(jié)構(gòu)體的格式化數(shù)據(jù)轉(zhuǎn)換成字符串儲存在了arr中,并輸出到屏幕上。
struct stu
{char name[39];int age;float score;
};int main()
{struct stu s = { "zhangsan", 38, 98.5 };char arr[100] = { 0 };sprintf(arr, "%s %d %lf", s.name, s.age, s.score);printf("%s\n", arr);return 0;
}
把字符串輸入到新創(chuàng)建的結(jié)構(gòu)體tmp中后將其格式化為結(jié)構(gòu)體數(shù)據(jù)
struct stu
{char name[39];int age;float score;
};int main()
{struct stu s = { "zhangsan", 38, 98.5 };char arr[100] = { 0 };struct stu tmp = { 0 };sprintf(arr, "%s %d %f", s.name, s.age, s.score);printf("%s\n", arr);sscanf(arr, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));printf("%s, %d, %f", tmp.name, tmp.age, tmp.score);return 0;
}
文件的隨機讀寫
fseek
fseek
是 C 標(biāo)準(zhǔn)庫中用于設(shè)置文件位置指針的函數(shù),通常用于在文件中移動讀寫位置。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
int fseek(FILE *stream, long offset, int whence);
stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要設(shè)置位置的文件流。offset
:偏移量,指定相對于?whence
?的移動距離。whence
:基準(zhǔn)點,指定相對位置的參考點,可以是?SEEK_SET
、SEEK_CUR
?或?SEEK_END
。
常用的 whence
參數(shù)取值如下:
SEEK_SET
:從文件開頭開始偏移。SEEK_CUR
:從當(dāng)前位置開始偏移。SEEK_END
:從文件末尾開始偏移。
fseek
函數(shù)將文件位置指針移動到指定的位置,以便進行后續(xù)的讀寫操作。
ftell
ftell
是 C 標(biāo)準(zhǔn)庫中用于獲取文件位置指針當(dāng)前位置的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
long ftell(FILE *stream);
stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要獲取位置的文件流。
ftell
函數(shù)返回當(dāng)前文件位置指針相對于文件起始位置的偏移量(以字節(jié)為單位)。通常情況下,ftell
函數(shù)會返回一個 long
類型的值,表示當(dāng)前位置的偏移量。
rewind
rewind
是 C 標(biāo)準(zhǔn)庫中用于將文件位置指針重新定位到文件的起始位置的函數(shù)。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
void rewind(FILE *stream);
stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要重新定位位置的文件流。
rewind
函數(shù)將文件位置指針移動到文件的起始位置,相當(dāng)于使用 fseek(stream, 0L, SEEK_SET)
將文件位置指針移動到文件開頭的操作。
使用部分
fseek的使用
SEEK_SET
:從文件開頭開始偏移。
SEEK_CUR
:從當(dāng)前位置開始偏移。
SEEK_END
:從文件末尾開始偏移。
ftell的使用
根據(jù)ftell的特性,配合fseek可統(tǒng)計文件中的字符數(shù)。當(dāng)然不止這一種,根據(jù)ftell函數(shù)的特性可開發(fā)除不同的用法。
int main()
{FILE* pf = fopen("data.txt", "w");if (pf == NULL){perror("fopen");return 1;}//寫文件fputs("abcdefg", pf);fclose(pf);pf = fopen("data.txt", "r");long size = 0;int ch = 0;fseek(pf, 0, SEEK_END);ch = fgetc(pf);size = ftell(pf);printf("%ld bytes.\n", size);//關(guān)閉文件fclose(pf);pf = NULL;return 0;
}
rewind的使用
int main()
{FILE* pf = fopen("data.txt", "w");if (pf == NULL){perror("fopen");return 1;}//寫文件fputs("abcdefg", pf);fclose(pf);pf = fopen("data.txt", "r");int ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);rewind(pf);ch = fgetc(pf);printf("%c\n", ch);//關(guān)閉文件fclose(pf);pf = NULL;return 0;
}
文件讀取結(jié)束的判定
feof
在 C 標(biāo)準(zhǔn)庫中,feof
函數(shù)用于檢查文件流的結(jié)束標(biāo)記,判斷文件是否已經(jīng)結(jié)束。它的原型定義在 <stdio.h>
頭文件中,通常的函數(shù)原型如下:
int feof(FILE *stream);
stream
:指向?FILE
?結(jié)構(gòu)體的指針,表示要檢查是否到達文件結(jié)尾的文件流。
feof
函數(shù)檢查給定文件流的結(jié)束標(biāo)記。如果文件流的結(jié)束標(biāo)記被設(shè)置,則 feof
返回非零值(即真),表示文件已經(jīng)結(jié)束;否則返回 0(假),表示文件尚未結(jié)束。
注意:在文件讀取的過程中不能用feof函數(shù)的返回值直接判定文件是否結(jié)束。
1.判斷文本文件是否結(jié)束,判斷返回值是否為EOF
2.二進制文件的讀取結(jié)束判斷,判斷返回值是否小于實際要讀的個數(shù)。
fread判斷返回值是否小于實際要讀的個數(shù)。
文本文件例子:
int main()
{int c;//int,非char,要求處理EOFFILE* pf = fopen("data.txt", "w");if (!pf){perror("fopen");return EXIT_FAILURE;}while (c = fgetc(pf) != EOF){putchar(c);}if (ferror(pf)){puts("I/O error when reading");}else if (feof(pf)){puts("End of file reached successfully");}fclose(pf);return 0;
}
二進制文件的例子:
#include <stdio.h>
enum { SIZE = 5 };
int main(void)
{double a[SIZE] = { 1.,2.,3.,4.,5. };FILE* fp = fopen("test.bin", "wb"); // 必須用二進制模式fwrite(a, sizeof * a, SIZE, fp); // 寫 double 的數(shù)組fclose(fp);double b[SIZE];fp = fopen("test.bin", "rb");size_t ret_code = fread(b, sizeof * b, SIZE, fp); // 讀 double 的數(shù)組if (ret_code == SIZE) {puts("Array read successfully, contents: ");for (int n = 0; n < SIZE; ++n) printf("%f ", b[n]);putchar('\n');}else { // error handlingif (feof(fp))printf("Error reading test.bin: unexpected end of file\n");else if (ferror(fp)) {perror("Error reading test.bin");}}fclose(fp);
}
文件緩沖區(qū)
