Файловый тип данных. Операции с файлами: открытие, закрытие, запись, чтение, дозапись. Функции файлового ввода/вывода
Файлы
Основные функции для работы с файлами
Массивы. Одномерные численные и символьные массивы. Основные алгоритмы поиска в одномерных массивах. Вариации вывода массивов
Объявление массива
Одномерные числовые массивы
Начальная инициализация и обнуление массива
Двумерные числовые массивы
Работа с массивами
Образование новых массивов в процессе работы программы

Файловый тип данных. Операции с файлами: открытие, закрытие, запись, чтение, дозапись

1. Файловый тип данных. Операции с файлами: открытие, закрытие, запись, чтение, дозапись. Функции файлового ввода/вывода

информации.

2. Файлы

• Ввод/вывод информации с использованием
файлов и потоков осуществляется с
помощью функций стандартной
библиотеки (заголовочный файл stdio.h).

3.

Указатель файла
Указатель файла – это указатель на
структуру типа FILE
FILE * file = 0
переменная file символизирует пустой
файловый поток

4.

Открытие файла
fopen() - открывает поток и связывает с
этим потоком определенный файл.
file = fopen("example.txt","w");
Параметр 1 – путь к файлу;
Параметр 2 – идентификатор, отвечающий
за те действия, которые мы собираемся
совершить с этим файлом

5.

6.

Проверка на существование файла
Если файла, который мы пытаемся открыть для
чтения, не существует, то функция fopen()
вернет ноль и файловый поток будет равен
нулю.
FILE * file;
if ((file = fopen("example.txt","r")) == 0) {
printf("Ошибка при открытии файла
example.txt.\n");
exit(1);
}

7. Основные функции для работы с файлами

• fclose(file) – закрытие файла;
• rename(старое_имя, новое_имя);
• remove(“input.txt”) – удаление файла;
• rewind(указатель файлового потока) –
возвращение курсора в начало файла;
• mkdir(“new_folder”) – создает новый каталог;
• rmdir(имя_каталога) – удаление каталога
• getcwd(строка, длина) – возвращает путь к
текущей директории;
• chdir(путь) – меняет текущую директорию

8. Массивы. Одномерные численные и символьные массивы. Основные алгоритмы поиска в одномерных массивах. Вариации вывода массивов

на экран. Двумерные
массивы и массивы строк.
Перестановка и сортировка в
двумерных массивах.

9.

Массив – это набор однотипных элементов,
имеющих одно имя, расположенных в
памяти непосредственно друг за другом,
доступ к которым осуществляется по
индексу. различны.

10. Объявление массива

тип имя_массива [количество элементов] ;

11. Одномерные числовые массивы

#define F 120
#define SIZE 45
int array[F];
double a[F], marks[SIZE];
int positive_numbers[F],
negativ_numbers[F];

12. Начальная инициализация и обнуление массива

При объявлении массива можно инициализировать его
значения.
#define N 6
int array_1[N] = {1, 6, 2, 9, -5, 2};
Если указано недостаточное количество значений элементов,
то оставшиеся элементы заполняются нулями.
#define N 9
int array_2[N] = {0, -5};
Для того, чтобы обнулить весь массив при объявлении
достаточно написать следующее:
int array_2[N] = {0};

13.

Рассмотрим массив из пяти элементов (N = 5):
1. array[0]
2. array[1]
3. array[2]
4. array[3]
5. array[4]
Индекс последнего элемента в массиве – это индекс на единицу
меньший, чем размерность массива (N - 1). Объем памяти,
необходимый для хранения массива, определяется типом
данных, которые хранит массив.
Для одномерного массива количество байтов памяти вычисляется
следующим образом:
количество_байт = (int)sizeof(тип) × длина_массива
Функция sizeof() возвращает значения типа size_t, поэтому требуется
явно преобразовать эти значения в int. Если вывести на экран
адреса элементов массива, то можно увидеть, что они
расположены друг за другом и отличаются друг от друга на число
занимаемых байт памяти (для целочисленного массива это 4
байт).

14. Двумерные числовые массивы

Объявление двумерного массива:
тип имя_массива [количество строк][количество столбцов];
#define N 10
#define M 7
int a[N][M];
double mass[N][5], num[40][12];
Подобно одномерным массивам при объявлении двумерного массива
можно инициализировать его значения:
int massiv[2][3] = {{0, 9, -6}, {-3, 0, -2}};
Если при такой инициализации указано недостаточное количество
значений элементов, то оставшиеся элементы заполняются нулями.
Обнуление двумерного массива:
int massiv[N][M] = {{0}};

15.

Для работы с двумерными массивами необходимо
пользоваться двумя циклами – по одному циклу на каждый
индекс. Соответственно, если вы работаете с трехмерным
массивом, то циклов будет три.
for (i = 0; i < N; i++) {
for (j = 0; j < M; j++) {
printf("%5d", array[i][j]);
}
printf("\n");
}
Здесь происходит вывод массива на экран. Внешний цикл
отвечает за индекс строки, а внутренний за индекс
столбца выводимого на экран элемента. Для каждого
значения внешнего цикла (цикл по строкам)
выполняются два действия: циклический вывод в строку
элементов текущей строки массива и переход на новую
строку. Таким образом, мы получаем прямоугольный
массив.

16.

Главная диагональ квадратного массива
характеризуется равенством индексов строки и
столбца (i == j). Соответственно, элементы ниже
главной диагонали имеют индекс строки всегда
больший, чем индекс столбца (i > j), а элементы выше
главной диагонали – индекс столбца всегда больше,
чем индекс строки (i < j).
• главная диагональ (i == j)
• выше главной диагонали (i < j)
• ниже главной диагонали (i > j)
Таким же образом, нетрудно заметить, что для
побочной диагонали справедливо:
• побочная диагональ (i + j == N - 1)
• выше побочной диагонали (i + j < N - 1)
• ниже побочной диагонали (i + j > N - 1)

17. Работа с массивами

Пример. Заполнить одномерный массив из 25ти
элементов целыми числами так, чтобы каждый элемент
равнялся квадрату своего индекса. Результат вывести на
экран в строку.
#define N 25
int i, array[N] = {0};
for (i = 0; i < N; i++) {
massiv[i] = i * i;
}
for (i = 0; i < N; i++) {
printf("%5d", array[i]);
}
Цикл for осуществляет обращение ко всем элементам массива
от первого с индексом 0 до последнего с индексом 24 и
каждому элементу присваивает значение i * i. После
окончания первого цикла, во втором цикле снова
происходит обращение ко всем элементам массива, и они
один за другим выводятся на экран в строку

18.

19.

20.

Пример. Выяснить, что больше по абсолютному значению: минимальный
элемент выше главной диагонали или максимальный элемент ниже
побочной диагонали квадратного двумерного массива (N˟N).

21. Образование новых массивов в процессе работы программы


заранее известно количество элементов в новом массиве (прямая
зависимость от количества элементов в исходном массиве);
• заранее неизвестно количество элементов в новом массиве (в этом
случае используется динамическая память).
Пример. Для одномерного массива из 16ти элементов образовать 4
новых массива, разделив исходный массив на 4 равные части.
#define N 16
int arr[N] = {0}, i = 0;
for(i = 0; i < N; i++) {
arr[i] = -15 + rand() % 31;
}
int h = 0;
int new_1[N/4], new_2[N/4], new_3[N/4], new_4[N/4];
for(i = 0, h = 0; i < N / 4; i++) {
new_1[h] = arr[i];
new_2[h] = arr[N / 4 + i];
new_3[h] = arr[2 * N / 4 + i];
new_4[h] = arr[3 * N / 4 + i];
h++;
}

22.

23.

24.

25.

Строки
Одномерные массивы чаще всего являются строками.
Строка - это одномерный массив символов, который
заканчивается нулевым символом конца строки. В
качестве нулевого символа выступает символ '\0'. Таким
образом, строка содержит символы, которые ее
составляют, и нулевой символ.
При объявлении массива символов, который предназначен
для хранения строки, необходимо предусмотреть место
для нулевого символа, то есть указать размер этого
массива при объявлении на единицу больше, чем число
предполагаемых символов в массиве. Например,
объявление массива из 10 символов должно выглядеть
следующим образом:
char name[11];

26.

При этом величина массива влияет всего лишь на количество
выделяемой для него памяти, сам массив может быть меньше этой
величины. Таким образом, размер массива при его объявлении — это
только максимально возможная длина строки, но, ни в коем случае, не
текущий ее размер. Таким образом, в отличие от числовых массивов,
длина строкового массива может как бы «изменяться» в пределах его
размера.
При объявлении строки она также может быть сразу инициализирована:
char str1[21] = "строка\n";
char str2[30] = {"Test string"};
В первом случае выделяется память для 20 символов, а заполняются
только семь из них (’\n’ – это один символ). Во втором случае заполняются
одиннадцать символов из 29ти выделенных в памяти.
Существует возможность вообще не указывать размер строки при ее
объявлении. В этом случае строку нужно инициализировать в
обязательном порядке. Размер такой переменной-строки вычисляется,
исходя из длины инициализирующей строки.
char special_size_str[] = "Это безразмерный массив";

27.

Консольный ввод/вывод строк
Функция scanf()
Для того чтобы прочитать строку, введенную с клавиатуры, и записать
ее в массив символов необходимо указать формат считываемой
информации как "%s". При указании переменной, в которую
необходимо записать прочитанную строку знак амперсанта не
ставится, так как имя строки это и есть ее адрес (указатель на нулевой
элемент массива).
#define STR_LEN 250
char str[STR_LEN], str_1[STR_LEN / 2];
scanf("%s%s", str, str_1);
Ограничением функции scanf() можно считать то, что она считывает
введенные символы до первого пробела и не всегда подходит для
считывания строк большой длины, состоящих из нескольких слов или
предложений.

28.

Функция printf()
Вывод строк с помощью функции printf() может
осуществляться двумя способами: напрямую (вывод
константной строки или строки-переменной) или с
указанием строки форматирования и ее параметров.
#define STR_LEN 250
char str[STR_LEN], str_1[STR_LEN / 2];
scanf("%s%s", str, str_1);
printf("Это вывод константной строки");
printf(str); //вывод без строки форматирования
printf("%s\n%s", str, str_1); //со строкой форматирования
Кроме scanf() и printf() для работы со строками
существуют специальные функции gets() и puts().

29.

Функция gets()
Функция gets() позволяет вводить строки с клавиатуры.
Параметром функции является имя массива символов, для
которого считывается значение.
#define STR_LEN 250
char str[STR_LEN];
gets(str);
Важнейшим ее отличием от функции scanf() является то, что
функция scanf() считывает строку до первого пробела, а функция
gets() считывает строку до знака перехода на новую строку. В
нижеследующем примере, если с клавиатуры ввести строку
"Первое слово съела корова", то в массив str1 запишется только
строка "Первое", а в массив str2 — полностью все предложение.
#define STR_LEN 250
char str1[STR_LEN], str2[STR_LEN];
scanf("%s", str1);
gets(str2);

30.

Среди ограничений функции gets() можно отметить то, что она считывает только
одну строковую переменную, в то время как scanf() может считывать значения
сразу нескольких переменных, среди которых могут быть и строки и числовые
значения. Кроме того, эта функция может приводить к ошибкам и многими
современными компиляторами расценивается как потенциально опасная.
Функция puts()
Функция вывода строк puts() так же в качестве аргумента принимает
строку, которая может быть представлена как переменной, так и
константной текстовой строкой (в том числе макросом).
#define STR "Строка введена успешно!" //макрос
char stroka[21]; //строка как переменная
// вывод константной строки
puts("Введите строку не длиннее 20ти символов\n");
gets(stroka);
puts(stroka); //вывод строки-переменной
puts(STR); //использование макроса в выводе

31.

При выводе строк между функциями puts() и printf() существует различие:
если строка выводится с помощью функции puts(), то после ее вывода
произойдет обязательный переход на новую строку. При использовании
функции printf() переместиться на новую строку можно, только если явно
указать управляющую последовательность "\n". Еще одним отличием
является то, что функция puts() может выводить только одну строку, в то
время как printf() способна выводить на экран любое количество объектов.
Пример. Вывести на экран первые N строк файла, указывая
номер строки.
int i = 0;
char str[500];
for (i = 0; i < N; i++) {
fgets(str, 500, file); //считываем строку из файла
//выводим строку на экран
printf("%dя строка - %s", i + 1, str);
}

32.

Общая таблица функций для работы со строками
Строковые переменные
Консольный ввод/вывод
gets(str);
scanf("%s", str);
puts(str);
printf("%s", str);
Файловый ввод/вывод
fgets(str, SIZE, file);
fscanf(file, "%s", str);
fputs(str, file);
fprintf(file, "%s", str);

33.

Особенности функций, работающих со строками.
Функция
Особенности функции
scanf();
fscanf();
gets();
fgets();
puts();
fputs();
Считывание символов до первого пробела
'\n' не дописывается в строку
'\n' дописывается в строку
'\n' добавляется после вывода
'\n' не добавляется после вывода

34.

Массивы строк
Объявление массивов строк происходит аналогично двумерным
числовым массивам. Индекс слева определяет количество строк, а
правый — максимальное количество символов в строке.
Объявим массив из 25ти строк с максимальной длиной каждой
строки 48 символов:
char str_array[25][49];
Для того, чтобы обращаться к отдельной строке массива строк,
нужно указывать только индекс этой строки. Например, вот так
выглядит ввод с клавиатуры третьей строки и вывод на экран пятой
строки:
gets(str_array[2]);
Пример. Вводить строки с клавиатуры и записывать их
puts(str_array[4]);
в массив строк str_arr[10][50] только тогда, когда длина
введенной строки превышает 15 символов.
char str_arr[10][50];
for(i = 0; i < 10; ) {
gets(str_arr[i]);
if (strlen(str_arr[i]) > 15) {
i++;
}
}
English     Русский Правила