Skip to content

Commit b42aa86

Browse files
committed
doc: add file_io document.
1 parent bd8fe53 commit b42aa86

File tree

4 files changed

+367
-1
lines changed

4 files changed

+367
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ C 和 C++ 的主要区别在于 C++ 支持类和对象,而 C 不支持
6969
- [C 递归](docs/c_functions_recursion.md)
7070
- [C 数学函数](docs/c_math.md)
7171
- [C 结构](docs/c_structs.md)
72+
- [C 中文件处理](docs/c_file_io.md)
7273
- [C 关键字 Keywords](docs/c_keywords.md)
7374

7475
<!--idoc:ignore:end-->

docs/c_file_io.md

Lines changed: 361 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
C 中文件处理
2+
===
3+
4+
在编程中,我们可能需要多次生成某些特定的输入数据。有时,仅在控制台上显示数据是不够的。要显示的数据可能非常大,在控制台上只能显示有限的数据,而且由于内存是容易丢失的,不可能一次又一次地恢复程序生成的数据。 但是,如果我们需要这样做,我们可以将其存储到本地文件系统中,该文件系统是易失的,并且每次都可以访问。 在这里,需要在 C 中处理文件。
5+
6+
C 中的文件处理使我们能够通过我们的 C 程序创建、更新、读取和删除存储在本地文件系统中的文件。 可以对文件执行以下操作。
7+
8+
- 创建新文件
9+
- 打开现有文件
10+
- 从文件中读取
11+
- 写入文件
12+
- 删除文件
13+
14+
## 文件处理函数
15+
16+
C 库中有许多函数可以打开、读取、写入、搜索和关闭文件。 文件函数列表如下:
17+
18+
函数 | 描述 Description
19+
---- | ----
20+
fopen() | 打开新文件或现有文件
21+
fprintf() | 将数据写入文件
22+
fscanf() | 从文件中读取数据
23+
fputc() | 将一个字符写入文件
24+
fgetc() | 从文件中读取一个字符
25+
fclose() | 关闭文件
26+
fseek() | 将文件指针设置到给定位置
27+
fputw() | 将整数写入文件
28+
fgetw() | 从文件中读取一个整数
29+
ftell() | 返回当前位置
30+
rewind() | 将文件指针设置为文件的开头
31+
<!--rehype:style=width: 100%; display: inline-table;-->
32+
33+
## 打开文件:fopen()
34+
35+
我们必须先打开一个文件,然后它才能被读取、写入或更新。`fopen()` 函数用于打开文件。`fopen()` 的语法如下所示:
36+
37+
```c
38+
FILE *fopen( const char * filename, const char * mode );
39+
```
40+
41+
fopen() 函数接受两个参数:
42+
43+
- 文件名(字符串)。 如果文件存储在某个特定位置,那么我们必须提及文件存储的路径。例如,文件名可以像“/some_folder/some_file.ext”。
44+
- 打开文件的模式。 它是一个字符串。
45+
46+
我们可以在 fopen() 函数中使用以下模式之一。
47+
48+
模式 Mode | 描述 Description
49+
---- | ----
50+
r | 以读取模式打开一个文本文件,允许读取文件。
51+
w | 以写模式打开一个文本文件,允许写入文件。
52+
a | 以追加模式打开一个文本文件,如果文件不存在,则会创建一个新文件。
53+
r+ | 以读写模式打开一个文本文件,允许读写文件。
54+
w+ | 以读写模式打开一个文本文件,允许读写文件。
55+
a+ | 以读写模式打开一个文本文件,允许读写文件。
56+
rb | 以读取模式打开二进制文件
57+
wb | 以写入模式打开二进制文件
58+
ab | 以追加模式打开二进制文件
59+
rb+ | 以读写模式打开二进制文件
60+
wb+ | 以读写模式打开二进制文件
61+
ab+ | 以读写模式打开二进制文件
62+
<!--rehype:style=width: 100%; display: inline-table;-->
63+
64+
65+
```c
66+
#include<stdio.h>
67+
void main( ) {
68+
FILE *fp;
69+
char ch;
70+
fp = fopen("file_handle.c", "r");
71+
while (1) {
72+
ch = fgetc(fp);
73+
if (ch == EOF)
74+
break;
75+
printf("%c", ch);
76+
}
77+
fclose(fp);
78+
}
79+
```
80+
81+
输出,将打印文件的内容:
82+
83+
```bash
84+
#include<stdio.h>
85+
void main( ) {
86+
FILE *fp;
87+
char ch;
88+
fp = fopen("file_handle.c", "r");
89+
while (1) {
90+
ch = fgetc(fp);
91+
if (ch == EOF)
92+
break;
93+
printf("%c", ch);
94+
}
95+
fclose(fp);
96+
}
97+
```
98+
99+
## 关闭文件:fclose()
100+
101+
`fclose()` 函数用于关闭文件。 对文件执行所有操作后,必须关闭该文件。`fclose()` 函数的语法如下:
102+
103+
```c
104+
int fclose(FILE *fp);
105+
```
106+
107+
## 写入文件:fprintf()
108+
109+
`fprintf()` 函数用于将字符集写入文件。 它将格式化的输出发送到流。
110+
111+
```c
112+
int fprintf(FILE *stream, const char *format [, argument, ...])
113+
```
114+
115+
```c
116+
#include <stdio.h>
117+
main() {
118+
FILE *fp;
119+
fp = fopen("file.txt", "w"); // 打开文件
120+
fprintf(fp, "Hello file by fprintf...\n"); // 将数据写入文件
121+
fclose(fp); // 关闭文件
122+
}
123+
```
124+
125+
## 读取文件:fscanf()
126+
127+
`fscanf()` 函数用于从文件中读取字符集。 它从文件中读取一个单词并在文件末尾返回 EOF。
128+
129+
```c
130+
int fscanf(FILE *stream, const char *format [, argument, ...])
131+
```
132+
133+
```c
134+
#include <stdio.h>
135+
main(){
136+
FILE *fp;
137+
char buff[255]; // 创建 char 数组来存储文件数据
138+
fp = fopen("file.txt", "r");
139+
while(fscanf(fp, "%s", buff)!=EOF) {
140+
printf("%s ", buff);
141+
}
142+
fclose(fp);
143+
}
144+
```
145+
146+
## C 文件示例:存储员工信息
147+
148+
让我们看一个文件处理示例,用于存储用户从控制台输入的员工信息。 我们将存储员工的 ID、姓名和薪水。
149+
150+
```c
151+
#include <stdio.h>
152+
void main() {
153+
FILE *fptr;
154+
int id;
155+
char name[30];
156+
float salary;
157+
fptr = fopen("emp.txt", "w+"); /* 打开文件 */
158+
if (fptr == NULL) {
159+
printf("文件不存在 \n");
160+
return;
161+
}
162+
printf("Enter the id\n");
163+
scanf("%d", &id);
164+
fprintf(fptr, "Id= %d\n", id);
165+
printf("Enter the name \n");
166+
scanf("%s", name);
167+
fprintf(fptr, "Name= %s\n", name);
168+
printf("Enter the salary\n");
169+
scanf("%f", &salary);
170+
fprintf(fptr, "Salary= %.2f\n", salary);
171+
fclose(fptr);
172+
}
173+
```
174+
175+
输出
176+
177+
```bash
178+
Enter the id
179+
1
180+
Enter the name
181+
kenny
182+
Enter the salary
183+
120000
184+
```
185+
186+
现在从当前目录打开文件。你会看到 emp.txt 文件。它有以下信息:
187+
188+
```bash
189+
Id= 1
190+
Name= kenny
191+
Salary= 120000
192+
```
193+
194+
## 写入文件:fputc()
195+
196+
`fputc()` 函数用于将单个字符写入文件。它将一个字符输出到一个字符串
197+
198+
```c
199+
int fputc(int c, FILE *stream)
200+
```
201+
202+
```c
203+
#include <stdio.h>
204+
main(){
205+
FILE *fp;
206+
fp = fopen("file1.txt", "w"); // 打开文件
207+
fputc('a',fp); // 将单个字符写入文件
208+
fclose(fp); // 关闭文件
209+
}
210+
```
211+
212+
## 读取文件:fgetc()
213+
214+
`fgetc()` 函数从文件中返回单个字符。它从流中获取一个字符。它在文件末尾返回 EOF:
215+
216+
```c
217+
int fgetc(FILE *stream)
218+
```
219+
220+
```c
221+
#include<stdio.h>
222+
#include<conio.h>
223+
void main() {
224+
FILE *fp;
225+
char c;
226+
clrscr();
227+
fp=fopen("myfile.txt", "r");
228+
while((c=fgetc(fp))!=EOF){
229+
printf("%c", c);
230+
}
231+
fclose(fp);
232+
getch();
233+
}
234+
```
235+
236+
## 写入文件:fputs()
237+
238+
`fputs()` 函数将一行字符写入文件。它将字符串输出到流
239+
240+
```c
241+
int fputs(const char *s, FILE *stream)
242+
```
243+
244+
```c
245+
#include<stdio.h>
246+
#include<conio.h>
247+
void main(){
248+
FILE *fp;
249+
clrscr();
250+
fp = fopen("myfile2.txt","w");
251+
fputs("hello c programming",fp);
252+
fclose(fp);
253+
getch();
254+
}
255+
```
256+
257+
## 读取文件:fgets()
258+
259+
`fgets()` 函数从文件中读取一行字符。 它从流中获取字符串:
260+
261+
```c
262+
char* fgets(char *s, int n, FILE *stream)
263+
```
264+
265+
```c
266+
#include<stdio.h>
267+
#include<conio.h>
268+
void main() {
269+
FILE *fp;
270+
char text[300];
271+
clrscr();
272+
273+
fp=fopen("myfile2.txt", "r");
274+
printf("%s", fgets(text, 200, fp));
275+
fclose(fp);
276+
getch();
277+
}
278+
```
279+
280+
## fseek()
281+
282+
`fseek()` 函数用于将文件指针设置为指定的偏移量。 它用于将数据写入所需位置的文件:
283+
284+
```c
285+
int fseek(FILE *stream, long int offset, int whence)
286+
```
287+
288+
`fseek()` 函数中使用了 3 个常量:`SEEK_SET``SEEK_CUR``SEEK_END`
289+
290+
```c
291+
#include <stdio.h>
292+
void main(){
293+
FILE *fp;
294+
fp = fopen("myfile.txt","w+");
295+
fputs("This is Book", fp);
296+
297+
fseek(fp, 7, SEEK_SET);
298+
fputs("Kenny Wong", fp);
299+
fclose(fp);
300+
}
301+
```
302+
303+
## rewind()
304+
305+
`rewind()` 函数将文件指针设置在流的开头。 如果您必须多次使用流,这很有用:
306+
307+
```c
308+
void rewind(FILE *stream)
309+
```
310+
311+
```c
312+
#include<stdio.h>
313+
#include<conio.h>
314+
void main(){
315+
FILE *fp;
316+
char c;
317+
clrscr();
318+
fp=fopen("file.txt", "r");
319+
while((c=fgetc(fp)) != EOF){
320+
printf("%c", c);
321+
}
322+
rewind(fp); // 将文件指针移动到文件的开头
323+
while((c=fgetc(fp)) != EOF){
324+
printf("%c", c);
325+
}
326+
fclose(fp);
327+
getch();
328+
}
329+
// 输出
330+
// Hello World!Hello World!
331+
```
332+
333+
如您所见,`rewind()` 函数将文件指针移动到文件的开头,这就是 `Hello World!` 被打印 2 次的原因。 如果你不调用 `rewind()` 函数,“Hello World!” 将只打印一次。
334+
335+
## ftell()
336+
337+
`ftell()` 函数返回指定流的当前文件位置。 我们可以使用 `ftell()` 函数在文件末尾移动文件指针后获取文件的总大小。 我们可以使用 `SEEK_END` 常量将文件指针移动到文件末尾。
338+
339+
```c
340+
long int ftell(FILE *stream)
341+
```
342+
343+
```c
344+
#include <stdio.h>
345+
#include <conio.h>
346+
void main (){
347+
FILE *fp;
348+
int length;
349+
clrscr();
350+
fp = fopen("file.txt", "r");
351+
fseek(fp, 0, SEEK_END);
352+
353+
length = ftell(fp);
354+
355+
fclose(fp);
356+
printf("Size of file: %d bytes", length);
357+
getch();
358+
}
359+
// 输出
360+
// Size of file: 18 bytes
361+
```

docs/c_keywords.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ typedef | 用以给数据类型取别名 | goto | 无条件跳转语句
2020
unsigned | 声明无符号类型变量或函数 | [break](./c_break_continue.md) | 跳出当前循环
2121
signed | 声明有符号类型变量或函数 | default | 开关语句中的“其他”分支
2222
extern | 声明变量是在其他文件正声明 | sizeof | 计算数据类型长度
23-
register | 声明寄存器变量 | return | 子程序返回语句(可以带参数,也可不带参数)循环条件
23+
register | 声明寄存器变量 | return | 子程序返回语句(可以带参数,也可不带参数)循环条件
24+
<!--rehype:style=width: 100%; display: inline-table;-->

idoc.chapters.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
- /: 结构
3838
- c_structs.md: C 结构 Structures
3939

40+
- /: 文件处理
41+
- c_file_io.md: C 文件处理
42+
4043
- /: 参考
4144
- c_keywords.md: C 关键字 Keywords
4245

0 commit comments

Comments
 (0)