207 lines
7.9 KiB
Markdown
207 lines
7.9 KiB
Markdown
---
|
||
title: File Handling
|
||
localeTitle: Обработка файлов
|
||
---
|
||
## Обработка файлов
|
||
|
||
### Введение
|
||
|
||
Если вы уже написали программу C `helloworld` , вы уже сделали файл IO в C! Поздравляем! : Тада:
|
||
|
||
```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 +** **\-** **открывает файл в режиме чтения и записи**
|
||
|
||
Вот пример чтения и записи данных в файл
|
||
|
||
\`\` \`с #включают
|
||
|
||
# включают
|
||
|
||
главный() { FILE \* fp; char ch; fp = fopen ("hello.txt", "w"); printf («Введите данные»); while ((ch = getchar ())! = EOF) { putc (ч, FP); } fclose (FP); fp = fopen ("hello.txt", "r");
|
||
|
||
while ((ch = getc (fp)! = EOF) Е ( "% С", ч);
|
||
|
||
fclose (FP); }
|
||
```
|
||
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.
|
||
```
|
||
|
||
с
|
||
|
||
# включают
|
||
|
||
# включают
|
||
|
||
int main () { // Инициализировать массив для хранения имени. char name \[20\]; // Прочитайте строку и сохраните ее для ее имени. scanf ("% s", имя); // Печать приветствия. printf («Привет,% s!», имя); return 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 <имя.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.
|
||
```
|
||
|
||
с
|
||
|
||
# включают
|
||
|
||
# включают
|
||
|
||
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) |