Практ №4 Ввод-вывод. Разработка программ вводавывода данных
Скачать 121.88 Kb.
|
Цель: получение практических навыков работы с файлами и использования средств форматирования данных. Символьные строки В отличие от других языков программирования, в классическом языке Си отсутствует строковый тип данных. Вместо него строка символов представляется в памяти компьютера как массив элементов типа char, в конце которого помещен нуль-символ ’\0’. Таким образом, строка – это последовательность символов, оканчивающаяся нуль-символом. Нуль-символ как шестнадцатеричная константа представляется – 0x00. Под определением строки понимается указание её символьного значения при объявлении. При определении строк символы строки заключаются в двойные кавычки. Существуют следующие способы определения строк: строковые константы; массивы символов; указатели на строки. Строковые константы. Как только компилятор встречает нечто, заключенное в двойные кавычки, он определяет это как строку и размещает ее символы последовательно в памяти, добавляя в конце ’\0’. Для определения констант используется директива #define. Пример: #define STR “Это строковая константа” . . . . . . . . . cout<< “ Пример строки: “ <<STR; Массивы символов. Для определения массива, необходимо сообщить компилятору требуемый размер памяти. Это можно сделать по-разному. Следующие три строки эквивалентны: char str [ ] = ”Слово”; char str [6] = ”Слово”; char str [6] = {’С’, ’л’, ’о’, ’в’, ’о’,’\0’}; Для того чтобы вывести символьную строку на экран, достаточно в операторе вывода указать только имя символьного массива: cout<<str; Этот способ применяется только для массивов символов. Для числовых массивов он не применим. Указатели на символьные строки. Определить строку можно также с помощью указателя. Например: char*pst = “еще строка”; Встретив такую запись, компилятор создает указанную строковую константу еще строка, а также переменную-указатель pst, которой присваивает адрес первого элемента строки. Для вывода на экран используется имя указателя: cout <<pst; Чтобы передать символьную строку в функцию, следует в качестве параметра функции указать символьный массив, а при вызове функции использовать имя передаваемой символьной строки. Пример.
Следует обратить внимание, что компилятор воспринимает такую передачу как передачу в функцию обычного массива. В параметрах для функции не нужно указывать размер строки, достаточно прописать тип char, имя переменной-массива и пустые квадратные скобки. Операции со строками Функции, проводящие операции со строками, определены в заголовочном файле strcpy(s,ct) – копирует строку ct в строку s, включая ’\0’; возвращает s. Здесь и далее ct и s принадлежат типу shar*. strcat(s,ct) – приписывает ct к s; возвращает s. strcmp(s,ct) – сравнивает s и ct; возвращает <0, если s < ct; 0, если s = ct; и >0, если s >ct (сравнение здесь - лексикографическое). strlen(s) – возвращает длину s. Рассмотрим пример. #include #include using namespace std; int main() { int m; char s1[]= " Kolodkina"; char s2[]= " Sahno”; cout< m=strcmp(s1,s2); if(m>0) cout< else cout< strcpy(s2,s1); cout< return 0; } На экран будет выведено: В библиотеке <cstring> есть и функции поиска. Так, функция strchr(s, chr) производит поиск первого вхождения символа chr в строке s. В случае удачного поиска функция возвращает указатель на место первого вхождения символа chr. Если символ не найден, то возвращается ноль. Рассмотрим пример использования функции strchr(s, chr), в котором в строку "Seven Zero Null" необходимо перед словом "Null" вставить слово "One". #include #include using namespace std; int main() { char cs[20] = "Seven Zero Null"; char str[5]; // определяем место первого вхождения (указатель) буквы 'N' в строке char*sn=strchr(cs,'N'); strncpy(str,sn,4); // копируем "Null" в str strcpy(sn,"One "); // на место "Null" ставим "One " strcat(cs,str); // добавляем в конец строки "Null" cout << cs << endl; return 0; } Вид экрана: Тип данных «строка» В современном стандарте C++ определен класс с функциями для организации работы со строками, который подключается с помощью директивы: #include Существует три причины для включения в C++ стандартного класса string: непротиворечивость данных (строка теперь определяется самостоятельным типом данных), удобство (программист может использовать стандартные С++-операторы) и безопасность (границы массивов отныне не будут нарушаться). Следует иметь в виду, что все вышеперечисленное не означает, что вы должны отказываться от использования обычных строк с завершающим нулем. Они по-прежнему остаются самым эффективным средством реализации строк. Но если скорость не является для вас определяющим фактором, использование нового класса string даст вам доступ к безопасному и полностью интегрированному способу обработки строк. Вот некоторые операторы, которые определены для типа string:
Эти операторы позволяют использовать объекты типа string в обычных выражениях и избавляют программиста от необходимости вызывать такие функции, как strcpy() или strcat(). Пример. #include #include using namespace std; int main() { setlocale(0,""); string str1("Тип string позволяет эффективно "); string str2("работать со строками."); string str3; // Присваивание строк. str3 = str1; cout <<"str1: "< // Конкатенация двух строк. str3 = str1 + str2; cout << str3 << "\n"; // Сравнение строк. if(str2 > str1) cout << "str2 > str1\n"; else cout << "str2 < str1\n"; if(str3 == str1 + str2) cout << "str3 == str1+str2\n"; // Ввод строки. cout << "Введите строку: "; cin >> str3; cout << str3; return 0; } Вид экрана: Важно также отметить, что в предыдущей программе размер строк не задается. Переменные типа string автоматически получают размер, нужный для хранения заданной строки. Таким образом, при выполнении операций присваивания или конкатенации строк строка-приемник увеличится по длине настолько, насколько это необходимо для хранения нового содержимого строки. При обработке string-строк невозможно выйти за границы строки. Именно этот динамический аспект string-строк выгодно отличает их от строк с завершающим нулем (которые часто страдают от нарушения границ). Форматирование данных с помощью манипуляторов Одним из способов форматирования информации в С++ является использование манипуляторов ввода/вывода. Манипулятор – это ключевое слово языка С++, которое применяется в выражениях ввода/вывода для управления информацией ввода/вывода. Манипуляторы различают с параметрами и без параметров. Например: dec – установка флага dec (вывод информации в десятичной форме) – манипулятор без параметра setw(15) – задание ширины поля вывода в 15 позиции – манипулятор с параметром. Для того, чтобы в программе можно было использовать манипуляторы с параметрами, необходимо в нее включить заголовок <iomanip>. Некоторые манипуляторы приведены в следующей таблице.
Пример с использованием манипуляторов. #include <iostream> #include <iomanip> int main() { cout<<hex <<100 << endl; cout<<oct <<10 << endl; cout<<setfill(‘Х’)<<setw(10)<<100; cout<<’ ‘<<”Red nose.”< return 0; } Первый манипулятор hex сообщает потоку, что необходимо выводить целые числа в шестнадцатеричной системе счисления и выводит 100 в шестнадцатеричной системе счисления. Затем манипулятор oct сообщает, что следующий вывод необходимо сделать в восьмеричной СС, и выводит 10 в восьмеричной СС. В следующей строке манипулятор setfill(‘Х’) предписывает заполнять пустые места символом ‘Х’, а setw(10) устанавливает ширину поля вывода, равную десяти, в которую выводится число 100 и строка Red nose. Результат выполнения программы: 64 12 ХХХХХХХ100 Red nose. Организация работы с файлами Для реализации файлового ввода/вывода в программу необходимо включить директиву: #include < fstream >. При работе с файлами следует соблюдать следующий порядок. Вначале необходимо создать поток для работы с файлом. Для этого объявляется его имя с соответствующим типом потока. Например: ifstream in; - создан поток ввода из файла с именем in. 2) После создания потока, необходимо установить связь файла с потоком. Это производится с помощью функции open(). Например, для того чтобы связать созданный поток in с файлом, допустим с именем one.txt, необходимо записать: in.open(“one.txt”); - это означает, что файл one связан с потоком in (для ввода данных). 3) Сделать проверку открытия файла: .. if(!in) cout<<”Error of file opening”; 4) После того, как файл открыт, работа с ним производится с помощью операторов ввода/вывода: “<<” и “>>”, так же, как и со стандартными потоками cin и cout, только вместо этих потоков необходимо использовать созданные потоки. Для нашего примера ввод из файла будет обеспечиваться инструкцией: in >> ...; Вся информация в файле хранится в том же формате, как если бы она находилась на экране. Поэтому, если информация выводится в файл, то он представляет собой файл с отформатированным текстом. 5) После работы с файлом его необходимо закрыть с помощью функции close(). Для нашего примера это запишется: in.close(); Пример программы работы с файлами, в которой создается файл для вывода и в него записывается информация, после чего он закрывается. Затем файл открывается для ввода и оттуда считывается информация в заранее подготовленные переменные. #include #include #include using namespace std; int main() { ofstream tofile; //создание потока вывода tofile.open(“first”); //открытие файла 10>100> |