freeCodeCamp/guide/chinese/c/file-handling/index.md

207 lines
6.5 KiB
Markdown
Raw Normal View History

---
title: File Handling
localeTitle: 文件处理
---
## 文件处理
### 介绍
如果您以前编写过C `helloworld`程序那么您已经在C中完成了文件IO恭喜 :田田:
```c
/* A simple hello world in C. */
#include <stdlib.h>
// Import IO functions.
#include <stdio.h>
int main() {
// This printf is where all the file IO magic happens!
// How exciting!
printf("Hello, world!\n");
return EXIT_SUCCESS;
}
```
文件处理是程序员最重要的部分。在C语言中我们使用文件类型的结构指针来声明文件
```c
FILE *fp;
```
C提供了许多内置函数来执行基本文件操作
**fopen** **\-** **创建新文件或打开现有文件**
**fclose** **\-** **关闭文件**
**getc** **\-** **从文件中读取一个字符**
**putc** **\-** **将一个字符写入文件**
**fscanf** **\-** **从文件中读取一组数据**
**fprintf** **\-** **将一组数据写入文件**
**getw** **\-** **从文件中读取一个整数**
**putw** **\-** **将一个整数写入文件**
**fseek** **\-** **将位置设置为欲望点**
**ftell** **\-** **给出文件中的当前位置**
**rewind** **\-** **将位置设置为起始点**
### 打开文件
**fopen**函数用于创建文件或打开现有文件
`c fp = fopen(const char filename,const char mode);`
在C中有许多打开文件的模式 **r** **\-** **以读取模式打开文件**
**w** **\-** **以书写模式打开或创建文本文件**
**a** **\-** **以追加模式打开文件**
**r +** **\-** **以读写模式打开文件**
**a +** **\-** **以读写模式打开文件**
**w +** **\-** **以读写模式打开文件**
这是一个读取和写入文件数据的示例
\`\`\`C #包括
# 包括
主要() { FILE \* fp; char ch; fp = fopen“hello.txt”“w”; printf“输入数据”; whilech = getchar= EOF{ putc将CHFP; } FCLOSEFP; fp = fopen“hello.txt”“r”;
whilech = getcfp= EOF 的printfC”CH;
FCLOSEFP; }
```
Now you might be thinking, "this justs prints text to my screen. How is this file IO?"
The answer isn't obvious at first, and needs some understanding about the UNIX system.
Under a UNIX system, everything is treated as a file, meaning you can read and write from it.
This means that your printer can be abstracted as a file since all you do with a printer is write with it.
It is also useful to think of these files as streams, since as you'll see later, you can redirect them with the shell.
So how does this relate to `helloworld` and file IO?
When you call `printf`, you are really just writing to a special file called `stdout`, short for __standard output__.
`stdout` represents, well, the standard output as decided by your shell, which is usually the terminal.
This explains why it printed to your screen.
There are two other streams (ie files) that are available to you with effort, `stdin` and `stderr`.
`stdin` represents the __standard input__, which your shell usually attaches to the keyboard.
`stderr` represents the __standard error__ output, which your shell usually attaches to the terminal.
### Rudimentary File IO, or How I Learnt to Lay Pipes
Enough theory, let's get down to business by writing some code!
The easist way to write to a file is to redirect the output stream using the output redirect tool, `>`.
If you want to append, you can use `>>`. _N.b. these redirection operators are in_ `bash` _and similar shells._
```
庆典
# 这将输出到屏幕......
。/你好,世界
# ...但这会写入文件!
./helloworld> hello.txt
```
The contents of `hello.txt` will, not surprisingly, be
```
你好,世界!
```
Say we have another program called `greet`, similar to `helloworld`, that greets you given your name.
```
C
# 包括
# 包括
int main{ //初始化一个数组以保存名称。 char name \[20\]; //读取一个字符串并将其保存到名称。 scanfs”名称; //打印问候语。 printf“你好s名字; 返回EXIT\_SUCCESS; }
```
Instead of reading from the keyboard, we can redirect `stdin` to read from a file using the `<` tool.
```
庆典
# 写一个包含名字的文件。
echo Kamala> name.txt
# 这将从文件中读取名称并将问候语打印到屏幕上。
./greet <name.txt
# \==>你好,卡玛拉!
# 如果您还想将问候语写入文件,可以使用“>”进行。
```
### The Real Deal
The above methods only worked for the most basic of cases. If you wanted to do bigger and better things, you will probably want to work with files from within C instead of through the shell.
To accomplish this, you will use a function called `fopen`. This function takes two string parameters, the first being the file name and the second being the mode.
Mode is basically permissions, so `r` for read, `w` for write, `a` for append. You can also combine them, so `rw` would mean you could read and write to the file. There are more modes, but these are the most used.
After you have a `FILE` pointer, you can use basically the same IO commands you would've used, except that you have to prefix them with `f` and the first argument will be the file pointer.
For example, `printf`'s file version is `fprintf`.
Here's a program called `greetings` that reads a from a file containing a list of names and writes to another file the greetings.
```
C
# 包括
# 包括
int main{ //创建文件指针 FILE \* names = fopen“names.txt”“r”; FILE \* greet = fopen“greet.txt”“w”;
```
// Check that everything is OK.
if (!names || !greet) {
fprintf(stderr, "File opening failed!\n");
return EXIT_FAILURE;
}
// Greetings time!
char name[20];
// Basically keep on reading untill there's nothing left.
while (fscanf(names, "%s\n", name) > 0) {
fprintf(greet, "Hello, %s!\n", name);
}
// When reached the end, print a message to the terminal to inform the user.
if (feof(names)) {
printf("Greetings are done!\n");
}
return EXIT_SUCCESS;
```
}
```
Suppose `names.txt` contains the following:
```
卡马拉 洛根 颂歌
```
Then after running `greetings` the file `greet.txt` will contain:
```
你好,卡玛拉! 你好,洛根! 你好,卡罗尔! \`\`\`
超级棒,对吧! :微笑:
### 更多信息:
* [Wikibooks文件IO页面](https://en.wikibooks.org/wiki/C_Programming/File_IO)