forked from ivan-igorevich/basic-c
files section
This commit is contained in:
parent
4d637e228c
commit
2a05b8ce3f
BIN
build/main.pdf
BIN
build/main.pdf
Binary file not shown.
85
main.tex
85
main.tex
|
@ -31,90 +31,11 @@
|
||||||
\import{sections/}{10-strings}
|
\import{sections/}{10-strings}
|
||||||
% 11 structs
|
% 11 structs
|
||||||
\import{sections/}{11-structs}
|
\import{sections/}{11-structs}
|
||||||
|
% 12 files
|
||||||
\section{Файлы}
|
\import{sections/}{12-files}
|
||||||
% Коллеги здравствуйте.
|
|
||||||
% За предыдущие занятия мы с вами познакомились почти со всеми существующими в языке С типами данных, как примитивными, так и ссылочными. Довольно подробно рассмотрели работу почти всех операторов языка. Пришло время поговорить о взаимодействии программы с операционной системой, а именно - о чтении и записи в файловую систему компьютера.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% Файловая система любого компьютера - это структура. Для языка С файл - это тоже структура. Структура, хранящая данные о положении курсора в файле, его название, буферы, флажки и прочие свойства. Файлы делятся на два основных типа - текстовые и бинарные. Мы рассмотрим работу с текстовыми.
|
|
||||||
% СЛАЙД О ФАЙЛОВОЙ СИСТЕМЕ
|
|
||||||
|
|
||||||
|
|
||||||
% Опишем переменную, хранящую указатель на нашу структуру. Вся основная работа будет проходить через неё. Для того, чтобы присвоить этой переменной указатель на какой-то реальный файл воспользуемся функцией fopen, которая возвращает указатель на адрес в памяти.
|
|
||||||
% FILE *f;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% Функция принимает в качестве аргументов имя файла в двойных кавычках и режим его открытия.
|
|
||||||
% Основных используемых режимов шесть - чтение, запись, добавление, двоичное
|
|
||||||
% чтение, двоичную запись и двоичное добавление. Функции записи и добавления создают файл в случае его отсутствия. А функция записи стирает файл, если он существует и не пустой.
|
|
||||||
% СЛАЙД О ВОЗМОЖНОСТЯХ И РЕЖИМАХ FOPEN
|
|
||||||
% Итак создадим текстовый файл с каким-то неожиданным названием вроде filename.txt, и скажем нашей программе, что нужно будет его создать, если его не существует, перезаписать, если существует, а дальше мы будем в него записывать данные.
|
|
||||||
% Имя файла в аргументе может быть как полным, вроде C:\FILE.TXT тогда файл будет создан в корне диска C, так и относительным, каким мы его указали сейчас. Это значит, что файл будет создан в той папке, в которой запускается наша программа.
|
|
||||||
% f = fopen(“filename.txt”, “w”);
|
|
||||||
|
|
||||||
|
|
||||||
% В случае, если файл не найден или по какой-то причине не создался, в переменную file запишется нулевой указатель, поэтому перед тем, как начать работу с файлом, нужно проверить, смогла-ли программа его открыть, для этого запишем условие если в наш указатель записался нулевой указатель, то дальнейшее выполнение функции Мэйн не имеет смысла.
|
|
||||||
|
|
||||||
% if(file == NULL) return 1;
|
|
||||||
|
|
||||||
|
|
||||||
% Если всё хорошо, можем записывать в файл данные. Для записи в файл есть несколько функций, мы воспользуемся самой простой и очевидной
|
|
||||||
% fprintf(); . В неё в качестве первого аргумента обязательно нужно передать указатель на файл, в который мы собираемся писать, а дальше можно использовать как знакомый нам printf() со всеми его удобствами, заполнителями, экранированными последовательностями и дополнительными аргументами. После того как мы закончили запись в файл его необходимо
|
|
||||||
% закрыть, вызвав функцию fclose();
|
|
||||||
|
|
||||||
|
|
||||||
% fprintf(f, “Hello, files! %s”, “we did it! \n”);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% fclose(f);
|
|
||||||
% Запустим наш проект и посмотрим что у нас получилось. Перейдем в проводник и увидим что в папке проекта появился файл filename.txt, в котором написано наше содержимое, откроем его с помощью блокнота.
|
|
||||||
|
|
||||||
|
|
||||||
% Теперь давайте рассмотрим не менее важную тему, а именно - чтение из файла. Для этого нужно его открыть в режиме чтения. Далее мы можем воспользоваться неожиданно похожей функцией - fscanf() чтобы прочитать форматированные значения из файла. Создадим массив из переменных типа char, назовем его word и, при помощи функции fscanf() считаем из файла некоторую строку, которую положим в этот массив. Далее выведем в консоль строку которую прочитали, для этого воспользуемся привычной нам функцией printf, а затем выведем пустую строку. Запустим нашу программу и увидим, что в консоль вывелось слово Hello, - т.е. до пробела, функция fscanf отлично отработала.
|
|
||||||
|
|
||||||
% char word[256];
|
|
||||||
% f = fopen(“filename.txt”, “r”);
|
|
||||||
|
|
||||||
% fscanf(f, “%s”, &word);
|
|
||||||
|
|
||||||
% printf(“%s”, word);
|
|
||||||
% puts(“”);
|
|
||||||
|
|
||||||
|
|
||||||
% Но сколько данных читать? Как узнать, что достигнут конец файла? Для этого придумали функцию feof() (FILE END OF FILE) возвращающую ноль, если конец файла не достигнут, и единицу если достигнут.
|
|
||||||
% Опишем цикл, который выведет в консоль все полученные сканом строки из нашего файла. Для этого мы циклически пройдемся по всему файлу пока не будет достигнут конец и будем выводить считанные строки в консоль
|
|
||||||
|
|
||||||
% Запустим наш проект и убедимся, что вывод в консоль полностью соответствует содержимому файла, и это было не так уж сложно.
|
|
||||||
% Не забудем в конце закрыть файл.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% char word[256];
|
|
||||||
% f = fopen(“filename.txt”, “r”);
|
|
||||||
% while(!feof(file)){
|
|
||||||
% fscanf(f, “%s”, &word);
|
|
||||||
% printf(“%s”, word);
|
|
||||||
% }
|
|
||||||
|
|
||||||
|
|
||||||
% fclose(f);
|
|
||||||
% puts(“”);
|
|
||||||
|
|
||||||
|
|
||||||
% На следующем уроке поговорим о распределении памяти. До скорой встречи!
|
|
||||||
|
|
||||||
\section{Распределение памяти}
|
\section{Распределение памяти}
|
||||||
|
Этот раздел находится в конце книги, но не по важности. Сильная сторона языка С не только в возможности работать с указателями, но и в возможности самостоятельно управлять выделяемой памятью внутри программы. В языках высокого уровня данная возможность зачастую скрыта от программиста, чтобы по случайности программа не привела к зависанию среды виртуализации, не попыталась воспользоваться всей возможной оперативной памятью или не сломала операционную систему.
|
||||||
% Коллеги, здравствуйте.
|
|
||||||
% Это занятие находится в конце курса, но не по важности. Сильная сторона языка С не только в возможности работать с указателями, но и в возможности самостоятельно управлять выделяемой памятью внутри программы. В языках высокого уровня данная возможность зачастую скрыта от программиста, чтобы по случайности не подвесить среду виртуализации или не сломать операционную систему.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% Итак, как мы уже знаем, все переменные всех типов как-то хранятся в памяти, и до этого момента нас устраивало, как операционная система нам эту память выделяет. Но, пришло время взять бразды правления в свои руки. Процесс выделения памяти для программы называется memory allocation отсюда и название функции, которая выделяет память и пишет в предложенный идентификатор указатель на начало этой области. malloc(size); - она принимает в качестве аргумента размер выделяемой памяти. Как видим, функция возвращает пустоту, то есть область памяти будет зафиксирована, но не размечена. То есть это будет просто некоторая пустая область из n байт.
|
% Итак, как мы уже знаем, все переменные всех типов как-то хранятся в памяти, и до этого момента нас устраивало, как операционная система нам эту память выделяет. Но, пришло время взять бразды правления в свои руки. Процесс выделения памяти для программы называется memory allocation отсюда и название функции, которая выделяет память и пишет в предложенный идентификатор указатель на начало этой области. malloc(size); - она принимает в качестве аргумента размер выделяемой памяти. Как видим, функция возвращает пустоту, то есть область памяти будет зафиксирована, но не размечена. То есть это будет просто некоторая пустая область из n байт.
|
||||||
% СЛАЙД ПРО MALLOC() И АРГУМЕНТЫ
|
% СЛАЙД ПРО MALLOC() И АРГУМЕНТЫ
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
\section{Файлы}
|
||||||
|
В предыдущих разделах мы познакомились почти со всеми существующими в языке С типами данных, как примитивными, так и ссылочными. Довольно подробно рассмотрели работу почти всех операторов языка. Пришло время выйти за пределы программы (хотя бы в части хранения данных) и поговорить о взаимодействии программы с операционной системой, а именно - о чтении и записи в файловую систему компьютера. Файловая система \textit{любого} компьютера - \textbf{это структура}. Для языка С файл - это тоже структура. Структура, хранящая данные о положении курсора в файле, его название, буферы, флажки и прочие свойства. Файлы делятся на два основных типа - текстовые и бинарные. Мы рассмотрим работу с текстовыми, поскольку работа с бинарными практически ничем не отличается, а текст всё-таки проще воспринимается.
|
||||||
|
|
||||||
|
С места в карьер, опишем переменную, хранящую указатель на структуру <<файл>>. Вся основная работа будет проходить через неё. Для того, чтобы присвоить этой переменной указатель на какой-то реальный файл будем пользоваться функцией \code{fopen();}, которая возвращает указатель на адрес в памяти. Функция принимает в качестве аргументов имя файла в двойных кавычках и режим его открытия.
|
||||||
|
\begin{lstlisting}[language=C,style=CCodeStyle]
|
||||||
|
FILE *f;
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Основных используемых режимов шесть:
|
||||||
|
\begin{itemize}
|
||||||
|
\item чтение,
|
||||||
|
\item запись,
|
||||||
|
\item добавление,
|
||||||
|
\item двоичное чтение,
|
||||||
|
\item двоичная запись,
|
||||||
|
\item двоичное добавление.
|
||||||
|
\end{itemize}
|
||||||
|
\subsection{Запись}
|
||||||
|
Функции \textbf{записи и добавления} \textit{создают} файл в случае его отсутствия. А функция \textbf{записи} \textit{стирает} файл, если он существует и не пустой. Итак создадим текстовый файл с каким-то неожиданным названием, вроде \code{filename.txt}, и скажем нашей программе, что нужно будет его создать, если его не существует, перезаписать, если существует, а дальше мы будем в него записывать данные, то есть режим открытия будет \code{"w"}. Имя файла в аргументе может быть как полным (абсолютным), вроде \code{C:\\FILE.TXT} тогда файл будет создан в корне диска C, или \code{/home/user/file.txt}. Также имя файла может быть и относительным, каким мы его указали сейчас, это значит, что файл будет создан в той папке, в которой запускается наша программа.
|
||||||
|
\begin{lstlisting}[language=C,style=CCodeStyle]
|
||||||
|
f = fopen("filename.txt", "w");
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
В случае, если файл не найден или по какой-то причине не создался, в переменную \code{f} запишется нулевой указатель, поэтому перед тем, как начать работу с файлом, нужно проверить, смогла-ли программа его открыть, для этого запишем условие, что если в наш указатель записался нулевой указатель, то дальнейшее выполнение функции \code{int main (int argc, char *argv[])} не имеет смысла.
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=C,style=CCodeStyle]
|
||||||
|
if (file == NULL) return 1;
|
||||||
|
\end{lstlisting}
|
||||||
|
Если всё хорошо, можем записывать в файл данные. Для записи в файл есть несколько функций, мы воспользуемся самой простой и очевидной:\code{fprintf();}, в неё в качестве первого аргумента обязательно нужно передать указатель на файл, в который мы собираемся писать, а дальше можно использовать как знакомый нам \code{printf();} со всеми его удобствами, заполнителями, экранированными последовательностями и дополнительными аргументами. После того как мы закончили запись в файл его необходимо
|
||||||
|
закрыть, вызвав функцию \code{fclose();}
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=C,style=CCodeStyle]
|
||||||
|
fprintf(f, "Hello, files! %s", "we did it!\n");
|
||||||
|
fclose(f);
|
||||||
|
\end{lstlisting}
|
||||||
|
Запустив проект, посмотрим что у нас получилось. В терминале не будет никакого вывода, но если перейти в проводник, то можно увидеть, что в папке проекта появился файл \code{filename.txt}, в котором написано наше содержимое. Открывается такой текстовый файл любым обычным блокнотом
|
||||||
|
|
||||||
|
\subsection{Чтение}
|
||||||
|
Отлично, программа теперь умеет сохранять результаты своей работы в файлы, то есть у нас появилось ещё одно средство вывода информации, помимо терминала. Теперь давайте рассмотрим не менее важную тему, а именно - чтение из файла. Ведь тогда мы сможем не просто иначе выводить информацию, но и сохранять её на жёстком диске от запуска к запуску программы, а значит хранить какие-то настройки или промежуточные значения. Для этого нам нужно совершить несколько несложных действий с применением неожиданно знакомой функции \code{fscanf();} чтобы прочитать форматированные значения из файла:
|
||||||
|
\begin{itemize}
|
||||||
|
\item создать массив \code{char[]}, для примера, назовем его \code{word};
|
||||||
|
\item нужный файл открыть в режиме чтения;
|
||||||
|
\item при помощи функции \code{fscanf();} считать из файла некоторую строку, которую положим в этот массив.
|
||||||
|
\end{itemize}
|
||||||
|
Далее выведем в консоль строку которую прочитали, для этого воспользуемся привычной нам функцией \code{printf();} а затем выведем пустую строку. Запустим нашу программу и увидим, что в консоль вывелось слово \code{Hello}, функция \code{fscanf();} отлично отработала, прочитав все символы из файла до пробела.
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=C,style=CCodeStyle]
|
||||||
|
char word[256];
|
||||||
|
f = fopen("filename.txt", "r");
|
||||||
|
fscanf(f, "%s", &word);
|
||||||
|
printf("%s\n", word);
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Но сколько данных читать? Как узнать, что достигнут конец файла? Для этого придумали функцию \code{feof();} (англ. file: end of file) возвращающую ноль, если конец файла не достигнут, и единицу если достигнут. Опишем цикл, который выведет в консоль все полученные \code{fscanf();} строки из нашего файла. То есть, мы циклически пройдемся по всему файлу, пока не будет достигнут его конец и будем выводить считанные строки в консоль:
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=C,style=CCodeStyle]
|
||||||
|
char word[256];
|
||||||
|
f = fopen("filename.txt", "r");
|
||||||
|
while (!feof(file)) {
|
||||||
|
fscanf(f, "%s", &word);
|
||||||
|
printf("%s ", word);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
fclose(f);
|
||||||
|
\end{lstlisting}
|
Loading…
Reference in New Issue