Константы 6 страница
имя_потока.read (char *buffer, int N) ;
Примечание:
— функция read считывает N символов из входного потока и помещает считанные символы в переменную buffer.
Формат кода при неформатированном выводе в выходной поток:
имя_потока.write (const char *buffer, int N) ;
Примечание:
— функция write записывает N символов из переменной buffer в выходной поток.
Пример:
1)
#include<stdio.h> //0
int main()
{ FILE *filein, *fileout ; //1+3
filein=fopen(“file.txt”, “r”); //1
if (!filein) { printf (“Error: can’t open input file\n”) ; //2
return 1; } //2
else { printf (“Input file opened\n”); } //2
fileout=fopen(“file_.txt”, “w”) ; //3
if (!fileout) { printf(“Error: can’t open output file\n”) ; //4
return 1;} //4
else { printf (“Output file opened\n”) ; } //4
fseek(filein, 0, SEEK_END) ; //5
long lenfile=ftell(filein) ; //6
char *bufin=new char[lenfile+1] ; //7
rewind(filein); //8
fread(bufin, lenfile, 1, filein) ; //9
bufin[lenfile]= ‘\0’ ; //10
printf (“Filelength: %d byte. \n, lenfile”) ; //11
char *bufout=new char[lenfile] ; //12
long in=0, out=lenfile–1 ; //13
while (bufin[in]) //13
{ bufout[out]=bufin[in]; //13
in++; out– – ; //13
}
fwrite (bufout, lenfile, 1, fileout) ; //14
fclose (filein); printf(“Input file closed\n”) ; //15
fclose (fileout); printf(“Output file closed\n”) ; //16
delete []bufin; delete []bufout; //17
return 0;
}
2)
#include<fstream.h> //0, iostream.h подключается автоматически
int main()
{
ifstream filein(“file.txt”, ios :: in | ios :: nocreate) ; //1
if (!filein) { cout<<“Error: can’t open input file”<<endl; //2
return 1; } //2
else { cout<<“Input file opened”<<endl; } //2
ofstream fileout(“file_.txt”, ios :: out | ios :: trunc) ; //3
if (!fileout) { cout<<“Error: can’t open output file”<<endl; //4
return 1; } //4
else { cout<<“Output file opened”<<endl; } //4
filein.seekg(0, ios :: end); //5
long lenfile=filein.tellg(); //6
char *bufin=new char[lenfile+1] ; //7
filein.seekg(0, ios :: beg) ; //8
filein.read(bufin, lenfile) ; //9
bufin[lenfile]=‘\0’ ; //10
cout<<“File length: ”<<lenfile<<“ byte.”<<endl; //11
char *bufout=new char[lenfile] ; //12
long in=0, out=lenfile–1; //13
while (bufin[in]) //13
{
bufout[out]=bufin[in]; //13
in++; out– –; //13
}
fileout.write(bufout.lenfile) ; //14
filein.close(); cout<<“Input file closed”<<endl; //15
fileout.close(); cout<<“Output file closed”<<endl; //16
delete []bufin; delete []bufout; //17
return 0;
}
Результаты выполнения программ (пример 1 и 2), если содержимое файлов:
file.txt: 0123456789 test.
Информация в выходном файле: file_.txt: tset 9876543210
Информация на экране:
Input file opened
Output file opened
File length: 15 byte.
Input file closed
Output file closed
В примерах:
//0 — Подключение библиотек для работы с файлами в С или С++.
//1 — Объявление файлового потока, открывающего файл для чтения.
//2 — Проверка ошибок открытия файла для чтения.
//3 — Объявление файлового потока, открывающего файл для записи.
//4 — Проверка ошибок открытия файла для записи.
//5 — Установка счетчика позиции в конец читаемого файла для дальнейшего определения длины файла.
//6 — Определение длины файла lenfile.
//7 — Объявление вспомогательного массива размером [lenfile+1] для данных, считываемых из файла.
//8 — Установка счетчика позиции чтения из файла в начало файла.
//9 — Чтение всего файла одним блоком и запись данных во вспомогательный массив.
//10 — Запись символа ‘\0’ в конец строки (признак конца строки).
//11 — Вывод на экран информации о длине файла.
//12 — Создание вспомогательного массива выходных данных.
//13 — Обработка данных из массива входных данных и запись результата в массив выходных данных.
//14 — Запись данных из массива выходных данных в файл.
//15 — Закрытие потока (и файла), открытого для чтения.
//16 — Закрытие потока (и файла), открытого для записи.
//17 — Очистка динамической памяти от вспомогательных массивов входных и выходных данных.
6.3. Строки: операции с текстовыми файлами
Строка представляет собой массив символов, заканчивающийся нуль-символом ‘\0’, который является терминатором строки, т.е. признаком конца строки.
Примечание:
— из определения строки следует, что при объявлении строкового массива из 100 байт, в нем можно хранить строку длиной 99 символов, а один байт отводится под нуль-символ.
6.3.1. Операции над строками
В таблице 6.2 представлены допустимые операции для строк.
Таблица 6.2 — Допустимые операции для строк
Операция | Действие | Операция | Действие |
= | Присваивание | <= | Меньше или равно |
+ | Конкатенация | > | Больше |
+= | Добавление | >= | Больше или равно |
== | Равенство | [ ] | Индексация |
!= | Неравенство | << | Вывод |
< | Меньше | >> | Ввод |
Кроме перечисленных в таблице операций библиотека <stdlib.h> содержит функции преобразования строк в числа:
double atof (const char *string) ;
int atoi (const char *string) ;
long atol (const char *string) ;
Примечания:
— функция atof преобразует строку string в тип double;
— функция atoi преобразует строку string в тип int;
— функция atol преобразует строку string в тип long;
— обратное преобразование возможно с помощью функции sprintf().
6.3.2. Методы и функции ввода и вывода строк
Кроме методов и функций ввода и вывода строк, рассмотренных выше, существуют еще методы неформатированного чтения из потока.
Формат методов неформатированного чтения из потока:
get (char *buffer, int N, char ‘lim’) ;
getline (char *buffer, int N, char ‘lim’) ;
Примечания.
Функция get считывает или N–1 символов из потока, или пока не встретится символ ‘lim’, и копирует их в символьную строку buffer. Вместо символа ‘lim’ в строку buffer записывается признак конца строки ‘\0’. В программу возвращает ссылку на текущий поток.
Функция getline аналогична функции get, но копирует в строку buffer символ ‘lim’.
Также существуют функции форматированного чтения из строки и записи в строку.
Формат записи функций форматированного чтения из строки и записи в строку:
int sprintf (char *buffer, const char *format [,arg, …]) ;
int sscanf (char *buffer, const char *format [,addr, …]) ;
Примечания:
— функция sprintf выводит в строку buffer значения переменных arg, … в формате, определенном строкой format;
— функция sscanf считывает данные из строки buffer в формате, определенном строкой format, и передает их переменным по адресам addr, …;
— параметры форматирования данных в функциях sprintf и sscanf аналогичны параметрам функций printf и scanf.
6.3.3. Функции работы со строками библиотеки <string.h>
В библиотеке <string.h> хранится широкий набор функций для работы со строками. Рассмотрим некоторые их них.
Формат записи функции добавления strcat:
char *strcat (char *dest, const char *str) ;
Примечание.
Функция добавляет в конец строки dest строку str и ‘\0’, результат записывает в dest.
Формат записи функции добавления с определением максимального количества добавляемых символов strncat:
char *strncat (char *dest, const char *str, size_t N) ;
Примечание.
Функция добавляет в конец строки dest не более N символов строки str и ‘\0’, результат записывает в dest.
Формат записи функции копирования strcpy:
char *strcpy (char *dest, const char *str) ;
Примечание.
Функция копирует в строку dest строку str, включая ‘\0’.
Формат записи функции копирования с определением максимального количества копируемых символов strncpy:
char *strncpy (char *dest, const char *str, size_t N) ;
Примечания:
— функция копирует в строку dest не более N символов строки str;
— если длина строки str больше или равна N, то символ ‘\0’ в конец строки dest не добавляется, в противном случае строка dest дополняется символами ‘\0’ до N-го символа.
Формат записи функции поиска символа в строке strchr:
char *strchr (const char *str, char *ch) ;
Примечания:
— функция возвращает указатель на первое найденное вхождение (положение) символа ‘ch’ в строке str, если нет искомого символа, то возвращает NULL;
— функция производит поиск в прямом направлении.
Формат записи функции поиска символа в строке в обратном направлении strrchr:
char *strrchr (const char *str, char *ch) ;
Примечания:
— функция аналогична функции strchr();
— функция производит поиск в обратном направлении.
Формат записи функции поиска (проверки на отсутствие) strspn:
size_t strspn (const char *str1, char *str2) ;
Примечаниe.
Функция возвращает индекс первого символа строки str1, отсутствующего в str2.
Формат записи функции поиска (проверка на совпадение) strсspn:
size_t strсspn (const char *str1, const char *str2) ;
Примечание.
Функция возвращает индекс первого символа строки str1, совпадающего с любым из символов строки str2.
Формат записи функции поиска (проверка на присутствие символа) strсpbrk:
char *strсpbrk (const char *str1, const char *str2) ;
Примечания:
— функция возвращает указатель на символ, являющийся первым вхождением любого из символов из str2 в строку str1;
— если одинаковых символов нет, то возвращается NULL.
Формат записи функции поиска (проверка на присутствие подстроки) strstr:
char *strstr (const char *str1, const char *str2) ;
Примечания:
— функция выполняет поиск первого вхождения подстроки str2 в строку str1;
— функция возвращает указатель на элемент из str1, с которого начинается str2, в случае удачного поиска и NULL в случае неудачного поиска.
Формат записи функции сравнения строк (с учетом регистра) strcmp:
int strcmp (const char *str1, const char *str2) ;
Примечание.
Функция сравнивает строки с учетом регистра символов и возвращает:
— значение < 0, если str1 < str2;
— значение = 0, если str1 == str2;
— значение > 0, если str1 > str2.
Формат записи функции сравнения строк (без учета регистра) stricmp:
int stricmp (const char *str1, const char *str2) ;
Примечание.
Функция сравнивает строки без учета регистра символов и возвращает значения аналогичные функции strcmp().
Формат записи функции сравнения строк с частью другой строки (с учетом регистра) strncmp:
int strncmp (const char *str1, const char *str2, size_t N) ;
Примечания:
— функция сравнивает строку str1 и первые N символов строки str2 с учетом регистра символов;
— функция возвращает значения аналогичные функции strcmp().
Формат записи функции сравнения строки с частью другой строки (без учета регистра) strnicmp:
int strnicmp (const char *str1, const char *str2, size_t N) ;
Примечания:
— функция сравнивает строку str1 и первые N символов строки str2 без учета регистра символов;
— функция возвращает значения аналогичные функции strcmp().
Форматы записи функции выделения лексемы strtok:
char *strtok (char *str1, const char *str2) ;
char *strtok (NULL, const char *str2) ;
Примечания:
— при использовании первого варианта формата записи функция сравнивает лексему из str1, отделенную началом str1 и любым символом из набора str2; при этом в строку str1 функция вставляет символ NULL непосредственно за последним символом лексемы
— второй вариант формата записи используется только при повторном вызове; при этом функция возвращает лексему из str1, отделенную любым символом из набора str2 и окончанием str1.
Формат записи функции вычисления длины строки strlen:
char *strlen (const char *string) ;
Примечание.
Функция возвращает длину строки string.
6.3.4. Функции классификации и преобразования символов библиотеки <ctype.h>
При работе со строками часто требуется знать и изменять состав строки. Определять, являются ли символы строки цифрами, буквами (каково регистра) или символами пунктуации, управления.
Формат записи функции классификации символов (букв или цифр) isalnum:
int isalnum (int ch) ;
Примечания:
— проверяет, является ли символ буквой или цифрой;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является буквой или цифрой, или false в противном случае.
Формат записи функции классификации символов (букв) isalpha:
int isalpha (int ch) ;
Примечания:
— проверяет, является ли символ буквой;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является буквой, или false в противном случае.
Формат записи функции классификации символов (букв нижнего регистра) islower:
int islower (int ch) ;
Примечания:
— проверяет, является ли символ буквой нижнего регистра;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является буквой нижнего регистра, или false — в противном случае.
Формат записи функции классификации символов (букв верхнего регистра) isupper:
int isupper (int ch) ;
Примечания:
— проверяет, является ли символ буквой верхнего регистра;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является буквой верхнего регистра, или false в противном случае.
Формат записи функции классификации символов (цифр) isdigit:
int isdigit (int ch) ;
Примечания:
— проверяет, является ли символ цифрой;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является цифрой, или false в противном случае.
Формат записи функции классификации символов (шестнадцатеричных цифр) isxdigit:
int isxdigit (int ch) ;
Примечания:
— проверяет, является ли символ шестнадцатеричной цифрой;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является символом шестнадцатеричной цифры, или false в противном случае.
Формат записи функции классификации символов (пунктуации) ispunct:
int ispunct (int ch) ;
Примечания:
— проверяет, является ли символ символом пунктуации;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является символом пунктуации, или false в противном случае.
Формат записи функции классификации символов (разграничителей) isspace:
int isspace (int ch) ;
Примечания:
— проверяет, является ли символ разграничительным;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является пробелом или табуляцией, или символом новой строки или страницы (9 … 13, 32) или false в противном случае.
Формат записи функции классификации символов (ASCII) isascii:
int isascii (int ch) ;
Примечания:
— проверяет, принадлежит ли символ таблице ASCII;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является символом таблицы ASCII (0 … 127), или false в противном случае.
Формат записи функции классификации символов (управляющих) iscntrl:
int iscntrl (int ch) ;
Примечания:
— проверяет, является ли символ управляющим;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является управляющим (127, 0 … 31), или false в противном случае.
Формат записи функции классификации символов (видимых) iscntrl:
int isgraph (int ch) ;
Примечания:
— проверяет, является ли символ видимым;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является видимым (33 … 126), или false в противном случае.
Формат записи функции классификации символов (печатаемых) isprint:
int isprint (int ch) ;
Примечания:
— проверяет, является ли символ печатаемым;
— выделяет младший байт параметра ch и возвращает значение true, если символ ch является печатаемым (видимые+пробел: 32 … 126), или false в противном случае.
Формат записи функции преобразования символов (в символ нижнего регистра) tolower:
int tolower (int ch) ;
Примечания:
— функция преобразует символ в символ нижнего регистра;
— функция получает параметр ch и возвращает его в нижнем регистре;
— в параметре ch используется только младший байт.
Формат записи функции преобразования символов (в символ верхнего регистра) toupper:
int toupper (int ch) ;
Примечания:
— функция преобразует символ в символ верхнего регистра;
— функция получает параметр ch и возвращает его в верхнем регистре;
— в параметре ch используется только младший байт.
Формат записи функции преобразования символов (в символ ASCII) toascii:
int toascii (int ch) ;
Примечания:
— функция преобразует символ в символ таблицы ASCII;
— функция получает параметр ch и возвращает его в диапазоне значений таблицы ASCII (0 … 127).
Пример:
/* Пример использования функции tolower() : */
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int length, i ;
char *string= “THIS IS A STRING.” ;
length=strlen(string) ;
for(i=0; i<length; i++)
{
string[i]=tolower(string[i]) ;
}
printf(“%s\n”, string) ;
return 0;
}
Результат выполнения программы:
this is a string.
6.4. Лекция 18. Операции со структурами и бинарными файлами
Самым простейшим вариантом бинарного файла является файл, хранящий структуры, которые не ссылаются друг на друга, т.е. не образуют линейный список.
Примечание.
Для изучения данной темы необходимо ознакомиться с принципами операций со структурами (см. пункт 4.3.3, лекция 13) и операциями над строками и принципами работы с текстовыми файлами (см. пункт 6.3, лекция 17), поскольку принципы работы с бинарными файлами, содержащими структуры основываются на ранее изложенном материале.
Рассмотрим отличия текстового и простейшего бинарного файла.
Формат текстового файла изображен на рис. 6.4.
Рис. 6.4 — Формат текстового файла
Пример текстового файла:
Alfimov V.V. 1981 2000.00
Esaulko A.I. 1981 1000.00
Shandrigin D.V. 1981 100.00
Формат текстового файла изображен на рис. 6.5.
Рисунок 6.5 — Формат бинарного файла
Пример бинарного файла изображен на рис. 6.6.
Рисунок 6.6 — Принтскрин примера бинарного файла
Примечание:
Для получения дополнительной информации смотрите методические указания к выполнению лабораторной работы №12 по дисциплине «Информатика и вычислительная техника» для студентов дневной формы обучения направления 6.050901 «Радиотехника». В 2 ч. Ч.2. Работа с файлами и структурами данных на языке С/С++ /СевНТУ; сост. С.Н. Бердышев, А.В. Лукьянчиков — Севастополь: Изд-во СевНТУ, 2008. — 16 с.
6.5. Лекция 19. Списки: операции с динамическими структурами данных; организация списков и их обработка
В случае, когда память под структуры данных в программе выделяется по мере необходимости отдельными блоками, связанными друг с другом с помощью указателей, то такую организацию памяти называют динамическими структурами данных.
Наиболее часто используют следующие динамические структуры, способные изменять размер во время выполнения программы:
— линейные списки;
— стеки;
— очереди;
— бинарные деревья.
6.5.1. Линейные списки
Линейным списком называется структура данных, при которой логический порядок следования элементов задается с помощью указателей.
Линейные списки могут быть:
— односвязными линейными списками;
— двусвязными линейными списками;
— односвязными линейными кольцевыми списками.
Примечания:
— элементы любой динамической структуры данных представляют собой структуры;
— каждый элемент списка содержит ключ;
— ключом может выступать любое из полей данных.
Односвязным (однонаправленным) линейным списком называют список, в котором каждый элемент ссылается на следующий элемент.
Диаграмма связей односвязного линейного списка представлена на рис. 6.7.
Рисунок 6.7 — Диаграмма связей в односвязном линейном списке
Двусвязным (двунаправленным) линейным списком называют список, в котором каждый элемент ссылается на предыдущий и следующий элементы.
Диаграмма связей двусвязного линейного списка представлена на рис. 6.8.
Рисунок 6.8 — Диаграмма связей в двусвязном линейном списке
Кольцевым списком называют список, у которого первый и последний элементы связаны указателями.
Диаграмма связей односвязного кольцевого списка представлена на рис. 6.9.
Рисунок 6.9 — Диаграмма связей в односвязном кольцевом списке
Примеры:
1. Элемент односвязного списка:
struct node
{
int data1;
char data2[15] ;
…
node *next;
} ;
2. Элемент двусвязного списка:
struct node
{
int data1;
char data2[15];
…
node *next;
node *prev;
} ;
Над списками можно выполнять следующие операции:
— начальное формирование списка (создание 1-го элемента);
— добавление элемента в конец списка;
— чтение элемента с заданным ключом;
— вставка элемента в заданное место списка (до или после элемента с заданным ключом);
— удаление элемента с заданным ключом;
— упорядочивание списка по ключу.
Вставку элемента в список можно описать диаграммой, представленной на рис. 6.10.
Рисунок 6.10 — Диаграмма связей элементов двумерного списка при вставке элемента в заданное место
Примеры:
1. Формирование первого элемента двусвязного списка:
node *first(int d)
{
node *pv=new node; // – выделение памяти под элемент
pv–>d = d; // – присваивание значения полю данных
pv–>next = NULL; // – обнуление указателей на следующий
pv–>prev = NULL; // – и предыдущий элементы (их еще нет)
return pv; // – передача в программу указателя на
} // – первый элемент списка
2. Добавление элемента в конец двусвязного списка:
void append(node **pend, int d)
{ node *pv=new node; // – выделение памяти под элемент
pv–>=d; // – присваивание значения полю данных
pv–>next=NULL; // – обнуление (следующего эл-та еще нет)
pv–>prev=*pend; // – указывает конец списка
// (куда добавляется элемент)
(*pend)–>next=pv; // – в предыдущем эл-те устанавливается
// – указатель на добавляемый эл-т
*pend=pv; // – обновление указателя на конец списка
}
3. Поиск элемента двусвязного списка по ключу:
node *find(node *const pbeg, int d)
{
node *pv=pbeg; // – указатель на первый эл-т списка
while(pv)
{
if(pv–>d == d) break;// – если значение совпало, то выход
pv=pv–>next; // – выбор следующего эл-та списка
}
return pv; // – передача в программу указателя
// на найденный элемент списка
}
4. Вставка элемента двусвязного списка в заданное место списка:
node insert (node *const pbeg, node **pend, int key, int d)
{
if(node *pkey=find(pbeg, key))
{ node*pv=new node;
pv–>d=d;
// 1 – установка связи нового эл-та с последующим:
pv–>next=pkey–>next;
// 2 – установка связи нового эл-та с предыдущим:
pv–>prev=pkey;
// 3 – установка связи предыдущего эл-та с новым:
pkey–>next=pv;
// 4 – установка связи последующего эл-та с новым:
(pv–>next)–>prev=pv; }
return pv;
}
5. Удаление элемента двусвязного списка:
bool remove (node **pbeg, node **pend, int key)
{ if (node *pkey=find(pbeg, key)) // выдел. памяти под указ. на эл-т
{ if (pkey==*pbeg) // если в начале списка
{ *pbeg=(*pbeg)–>next;
(*pbeg)–>prev=0; }
else if (pkey==*pend) // если в конце списка
{ *pend=(*pend)–>prev;
(*pend–>next=0) }
else // если в середине списка
{ (pkey–>prev)–>next=pkey–>next;
(pkey–>next)–>prev=pkey–>prev; }
delete pkey; // освобождение памяти (удаление)
return true; } // выход : эл-т найден и удален
return false; } // выход : эл-т не найден
6.5.2. Стеки
Стек — это частный случай односвязного (однонаправленного) списка, добавление элементов в который и выборка из которого выполняется с одного конца, называемого вершиной стека.
Примечания:
— при чтении элемента он исключается из стека;
— работает стек по принципу «последний вошел, первым вышел» (LIFO);
Дата добавления: 2015-10-21; просмотров: 637;