- •Функции.
- •Вызов функции с переменным числом параметров
- •Функция main и её параметры.
- •Директивы препроцессора (прекомпилера).
- •Объявление указателей.
- •Модификатор const.
- •Операции.
- •Указатели на различные типы.
- •Указатель на void.
- •Применение указателей для передачи данных между функциями.
- •Массивы.
- •Индексация массивов.
- •Хранение массива в памяти. Адреса элементов. Хранение массива в памяти.
- •Массивы и константные указатели.
- •Статическое и динамическое выделение памяти.
- •Функции calloc, malloc, free
- •Функция realloc
- •Передача массивов в качестве аргументов функции.
- •Указатели на функции.
- •Библиотеки функций.
- •Функции форматированного ввода-вывода.
- •Функция printf().
- •%[Флаги] [Ширина] [.Точность] [{h | l | I | i32 | i64}]тип
- •Для чего нужен форматированный вывод.
- •Функция scanf().
- •Функции sprintf() и sscanf().
- •Функции fprintf() и fscanf().
- •Функции неформатированного ввода-вывода.
- •Работа со строковыми данными (стрингами). Представление строковых данных в языке c.
- •Функции работы со строками.
- •Потоковый ввод-вывод
- •Функции форматированного ввода-вывода.
- •Функция printf().
- •%[Флаги] [Ширина] [.Точность] [{h | l | I | i32 | i64}]тип
- •Для чего нужен форматированный вывод.
- •Функция scanf().
- •Функции sprintf() и sscanf().
- •Функции fprintf() и fscanf().
- •Функции неформатированного ввода-вывода.
- •Функции работы с файлами.
- •Потоковый ввод-вывод
- •Работа с потоками
- •Курсор.
- •Ввод-вывод отдельных символов и строк.
- •Форматированный ввод-вывод информации в файл.
- •Блочный потоковый ввод-вывод
- •Смена текущей позиции в файле. Проверка конца файла.
- •Функции доступа к файлам нижнего уровня.
- •Методы сортировки данных.
- •Введение
- •Сравнение методов сортировки
- •Программная реализация алгоритмов сортировки
- •Метод пузырька.
- •Метод обмена.
- •Метод вставки.
- •Метод Шелла.
- •Метод кучи (бинарной кучи).
- •Очередь
- •Линейный список
- •Физическое (машинное) представление линейных списков
- •Программные реализации структур данных. Стек. Реализация в виде массива.
- •Стек. Связанное представление.
- •Очереди. Реализация в виде массива.
- •Дерево. Связанное представление.
- •Рекурсивный вызов функций.
- •Структуры. Объединения. Перечисления.
- •Перечисление (enum).
- •Производные типы данных.
- •Структура (struct).
- •Побитовое описание полей структуры.
- •Объявление переменных, реализующих структуру.
- •Доступ к элементам структуры.
- •Объединение (union).
- •Вложенное описание структур и объединений.
- •Описание структур и объединений в виде пользовательского типа.
- •Передача структур и объединений в виде параметров функции.
- •Инициализация структур и объединений.
- •Выгода от использования структур
Работа с потоками
Процесс работы с файлами можно разделить на 3 основные части:
Открытие файла (потока). На этой стадии происходит инициализация всех процессов операционной системы, ответственных за работу с внешними носителями, в том числе, поиск файла.
Считывание данных из файла (потока) или запись данных в файл (поток). Считываемые данные поблочно считываются из файла в буфер в оперативную память, откуда потом побайтно попадают в программу. Записываемые программой в файл данные сначала помещаются в буфер, который по мере заполнения единым блоком записывается в файл.
Закрытие файла (потока). На этой стадии всё содержимое буфера, ещё не записанное в файл, записывается в него. Поэтому отсутствие операции закрытия файла может привести к тому, что часть данных, с точки зрения программы уже записанных в файл, будет потеряна. На этой же стадии освобождается память, выделенная операционной системой под буфер.
Прежде чем начать работать с потоком, его необходимо инициализировать - открыть. Для этого в C используется функция fopen.
FILE *fopen( const char *filename, const char *mode ); где
filename – имя файла (с полным путём или относительно текущего каталога).
mode – режим открытия файла.
Основные режимы работы формируется из 2 частей, первая из них отвечает за режим чтения / записи:
"r" |
Открытие файла для чтения. Если файл не существует, то функция возвращает ошибку (NULL). |
"w" |
Открытие файла для записи. Если файл уже существует, то его содержимое будет стёрто. |
"a" |
Открытие файла для добавления записей в уже существующий файл (без удаления его уже существующего содержимого). Если файл не существует, то его надо создать перед открытием потока с флагом "a". |
"r+" |
Открытие для чтения и записи (файл должен существовать). |
"w+" |
Открытие пустого файла для чтения и записи. Если файл уже существует, то его содержимое будет стёрто. |
"a+" |
Открытие файла для чтения и добавления записей в уже существующий файл (без удаления его уже существующего содержимого). Если файл не существует, то его надо создать перед открытием потока с флагом "a". |
Вторая часть cтроки, на которую указывает переменная mode, отвечвет за режим трансляции символов.
(пусто) |
Текстовый режим. Некоторые сочетания байтов (например, символы, отвечающие за перевод строки) транслируется функциями чтения / записи в виде 1 байта вместо нескольких байт, записанных в файле. |
T |
Модифицированный текстовый режим (только для компиляторов Microsoft). Дополнительная трансляция некоторых сочетаний символов в один символ. |
B |
Бинарный (двоичный) режим. Не производится никакой трансляции информации – содержимое файла считывается с точностью до байта. |
Например, при использовании режима "wb" файл (поток) будет открыт на запись в бинарном режиме.
При использовании режима "r" файл (поток) будет открыт на чтение в текстовом режиме. При этом некоторые символы функциями чтения будут возвращаться не точно в том виде, как они записаны в файле. Например, существуют два различных стандарта на запись символа перевода строки: в стандарте DOS/UNIX он кодируется одним символом с кодом 0x0d, а в стандарте Windows он кодируется двумя символами 0x0d и 0x0a, записанными один за другим. Для того, чтобы программист не беспокоился об этой разнице и программа работала бы для файлов обоих стандартов, в текстовом режиме оба варианта ("\x0D" и "\x0D\x0A") передаются пользователю в виде символа с кодом 0x0d.
При удачном завершении процесса открытии файла, функция fopen возвращает указатель на специальную структуру FILE (что такое структура будет рассказано позже), уникально идентифицирующую открытый с её помощью поток. В противном случае функция fopen возвращает NULL.
После вызова функции fopen всегда обязательно надо проверять возвращаемый результат и делать обработку ошибок. Например, типовая работа с файлами выглядит так:
FILE* stream;
// Открываем файл для чтения
if( (stream = fopen( "data", "r" )) == NULL )
printf( Не могу открыть файл 'data'\n" );
else
{
// Читаем / записываем в файл
…
// Закрываем файл
if( fclose( stream ) )
printf( "Не могу закрыть файл 'data' \n" );
}
По окончании работы с потоком его необходимо закрыть. Это делается с помощью функции
int fclose( FILE *stream );
которой в качестве аргумента передаётся указатель на идентификатор потока, полученный от функции fopen().
Функция fclose() возвращает 0 в случае успешного завершения (в отличие от fopen(), которая возвращает NULL в случае ошибочного завершения). Поток не может быть закрыт если файл по каким-либо причинам был блокирован операционной системой – в этом случае возвращается ненулевой код (равный константе EOF), индицирующий наличие ошибки. Заметим, что поток надо закрывать только в том случае, если он предварительно был успешно открыт, поэтому в вышеприведённом примере функция fclose() стоит внутри блока оператора if, выполняемого при успешном открытии файла.