Константы 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; просмотров: 591;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.208 сек.