logo
C# Программирование на языке высокого уровня. Среда разработки Microsoft Visual Studio.NET

ЛАБОРАТОРНАЯ РАБОТА № 2

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

1. Краткие теоретические сведения

Вывод, производимый методами System.Console.Write() и System.Console.WriteLine(), можно форматировать. Форматирование позволяет указывать формат целых чисел, чисел с плавающей точкой и других типов данных.

Управление форматом числовых данных

Пусть в программе определена переменная типа int с именем

value:

int value = 250;

До этого момента переменные выводились следующим образом:

System.Console.WriteLine ("value =" + value);

Результат вывода: value = 250

Можно вывести значение value, используя требуемое число позиций (например 5):

System.Console.WriteLine("value = {0, 5}", value);

Первое число в фигурных скобках означает номер переменной - это 0, что соответствует первой переменной value в списке метода System.Console.WriteLine(). Второе число в фигурных скобках означает количество позиций, отведенное для отображения переменной. В данном примере оно равно 5. При выводе переменной длина ее представления будет дополнена пробелами слева. Если количество позиций меньше чем число знаков переменной, то оно будет выведено без форматирования.

Можно задать форматирование для вывода каждой переменной:

int a = -12;

int b = 20;

System.Console.WriteLine("a = {0, 4}, b = {1, 3}", a, b);

Результат вывода: a = -12, b = 20

Форматированный вывод чисел с плавающей точкой немного более сложный. Предположим, определена переменная типа double с именем

myDouble:

double myDouble = 1234.56789;

Следующий пример выводит значения myDouble, отведя под него десять знакомест, и округлив его до трех цифр после запятой:

System.Console.WriteLine("myDouble = {0, 10:f3}"; myDouble);

Символы f3 в этом примере означают, что значение выводится как число с плавающей точкой (символ f) , в дробной части будет выведено три цифры.

Точно такое же форматирование можно применять для типов float и decimal. Например:

float myFloat = 1234.56789f;

System.Console.Write("myFloat ={0, 0:f3}"myFloat);

decimal myDecimal = 1234.56789m;

System.Console.Write("myDecimal = {0, 10:f3}", myDecimal);

Результат вывода:

myFloat = 1234.568;

myDecimal 1234.568;

В списке аргументов методов WriteLine или Write задается строка вида {n, w: спецификатор k} - где n определяет номер идентификатора из списка аргументов метода WriteLine, спецификатор - определяет формат данных, w - целая константа без знака, задает количество символов (длину поля), a k - количество позиций для дробной части значения идентификатора.

Для каждого типа данных существует своя форма представления. Данные сведены в таблицу 2.1.

Таблица 2.1

Тип данных

Форма

Целые

W

Числовые

Вещественные с фиксированной точностью

W:Fk

Вещественные в экспоненциальном формате

W:Ek

Логические

W

Символьные

W

Символы форматирования F, E (другие символы форматирования приведены в табл. 2.2) - определяют тип и характеристики объектов ввода-вывода. Параметр w - целая константа без знака, задает количество символов (длину поля), отводимых для ввода- вывода объекта. Параметр k - целая константа без знака определяет для числовых данных:

• количество позиций, для цифр в дробной части числа (форма F);

• количество позиций для цифр, в дробной части мантиссы числа (форма E или G).

Таблица 2.2

Символ

Формат

Значение

C или c

Денежный. По умолчанию ставит знак р. Изменить его можно с помощь объекта NumberFormatInfo

Задается количество десятичных разрядов.

D или d

Целочисленный (используется только с целыми числами)

Задается минимальное количество цифр. При необходимости результат дополняется начальными нулями

E или e

Экспоненциальное представление чисел

Задается количество символов после запятой. По умолчанию используется 6

F или f

Представление чисел с фиксированной точкой

Задается количество символов после запятой

G или g

Общий формат (или экспоненциальный, или с фиксированной точкой)

Задается количество символов после запятой. По умолчанию выводится целая часть

N или n

Стандартное форматирование с использованием запятых и пробелов в качестве разделителей между разрядами

Задается количество символов после запятой. По умолчанию - 2, если число целое, то ставятся нули

X или x

Шестнадцатеричный формат

P или p

Процентный

В качестве спецификаторов могут использоваться следующие значения:

Пример 1. Форматированный вывод данных различного типа.

public static void Main()

{

int a = -14;

float c = -0.00151f;

double i = 1234.56789;

bool l=false;

string name="Petrov";

System.Console.WriteLine("name = {0, 6}, l = {1, 4}", name,l);

System.Console.WriteLine("a ={0, 4}, c = {1,10:f5}, i =

{1,20:e8}", a,c,i);

System.Console.WriteLine(" ");

System.Console.WriteLine(" Для выхода нажмите на Enter");

System.Console.ReadLine();

}

Пример 2. Ввод в диалоге и форматированный вывод данных различного типа.

public static void Main()

{

int a; // = -14;

float c; // = -0.00151f;

double i; // = 1234.56789;

bool l; // = false;

string name; //="Petrov";

Console.WriteLine("Input фамилию ");

name = Console.ReadLine();

Console.WriteLine("Input a");

a = Convert.ToInt32(Console.ReadLine());

Console.WriteLine("Input c");

c = Convert.ToSingle(Console.ReadLine());

Console.WriteLine("Input i");

i = Convert.ToDouble(Console.ReadLine());

Console.WriteLine("Input l");

l = Convert.ToBoolean(Console.ReadLine());

System.Console.WriteLine(" Результаты форматирования

name = {0, 6}, l = {1, 4}", name,l);

System.Console.WriteLine("a ={0, 4}, c = {1,10:f5},

i = {2,20:e8}", a,c,i);

System.Console.WriteLine(" ");

System.Console.WriteLine("Для выхода нажмите на Enter");

System.Console.ReadLine();

}

Организация ввода вывода с использованием файлов

Сопрограммы выполняют операции ввода-вывода посредством потоков, которые построены на иерархии классов. Поток (stream) - это абстракция, которая генерирует и принимает данные. С помощью потока можно читать данные из различных источников (клавиатура, файл) и записывать в различные источники (принтер, экран, файл). Несмотря на то, что потоки связываются с различными физическими устройствами, характер поведения всех потоков одинаков. Поэтому классы и методы ввода-вывода можно применить ко многим типам устройств.

На самом низком уровне иерархии потоков ввода-вывода находятся потоки, оперирующие байтами. Это объясняется тем, что многие устройства при выполнении операций ввода-вывода ориентированы на байты. Однако для человека привычнее оперировать символами, поэтому разработаны символьные потоки, которые фактически представляют собой оболочки, выполняющие преобразование байтовых потоков в символьные и наоборот. Кроме этого, реализованы потоки для работы с int-, double-, short- значениями, которые также представляют оболочку для байтовых потоков, но работают не с самими значениями, а с их внутренним представлением в виде двоичных кодов.

Центральную часть потоковой С#-системы занимает класс Stream пространства имен System.IO. Класс Stream представляет байтовый поток и является базовым для всех остальных потоковых классов. Чтобы создать символьный поток нужно поместить объект класса Stream (например, FileStream) "внутрь" объекта класса StreamWriter или объекта класса StreamReader. В этом случае байтовый поток будет автоматически преобразовываться в символьный.

Класс StreamWriter предназначен для организации выходного символьного потока. Этот класс содержит несколько конструкторов. Так, например, создать экземпляр класса StreamWriter можно следующим образом:

StreamWriter fileOut = new StreamWriter(new FileStream("text.txt",

FileMode.Create, FileAccess.Write));

Эта версия конструктора позволяет ограничить доступ только чтением или только записью:

FileStream(string filename, FileMode mode, FileAccess how)

где:

1. параметры filename и mode имеют то же назначение, что и в предыдущей версии конструктора;

2. параметр how, определяет способ доступа к файлу и может принимать одно из значений, определенных перечислением FileAccess:

FileAccess.Read - только чтение;

FileAccess.Write - только запись;

FileAccess.ReadWrite - и чтение, и запись.

Другой вид конструктора позволяет открыть поток сразу через обращения к файлу:

StreamWriter(string name),

где параметр name определяет имя открываемого файла.

Например, обратиться к данному конструктору можно следующим образом:

StreamWriter fileOut = new StreamWriter("c: emp .txt");

И еще один вариант конструктора StreamWriter:

StreamWriter(string name, bool appendFlag),

где параметр name определяет имя открываемого файла; параметр appendFlag может принимать значение true - если нужно добавлять данные в конец файла, или false - если файл необходимо перезаписать. Например:

StreamWriter fileOut=new StreamWriter("t.txt", true);

Теперь для записи данных в поток fileOut можно обратиться к методу WriteLine. Это можно сделать следующим образом:

fileOut.WriteLine("test");

В данном случае в конец файла t.txt будет дописано слово test.

Класс StreamReader предназначен для организации входного символьного потока. Один из его конструкторов выглядит следующим образом:

StreamReader(Stream stream),