Российский Государственный Технологический Университет им. К.Э. Циолковского
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 5636 / 790 | Оценка: 3.96 / 3.45 | Длительность: 27:04:00
ISBN: 978-5-9556-0086-4
Лекция 11:

Ввод/вывод

Консольный ввод. Преобразование значений

Следует иметь в виду, что чтение информации из входного потока класса Console связано с получением из буфера клавиатуры СИМВОЛЬНЫХ последовательностей и в большинстве случаев предполагает дальнейшие преобразования этих последовательностей к соответствующему типу значений.

Консольный ввод предполагает использование уже известных статических (!) функций – членов класса Console:

  • Read() – читает следующий знак из стандартного входного потока:
    public static int Read();

    Возвращаемое значение:

    Следующий знак из входного потока или значение " –1 ", если знаков больше нет.

    Метод не будет завершен до окончания операции чтения, например при нажатии клавиши "Ввод". При наличии данных входной поток содержит ввод пользователя и зависящую от окружения последовательность знаков перехода на новую строку.

  • ReadLine() – считывает следующую строку символов из стандартного входного потока:
    public static string ReadLine();

    Возвращаемое значение:

    Следующая строка из входного потока или пустая ссылка, если знаков больше нет.

Строка определяется как последовательность символов, завершаемая парой escape-символов carriage return line feed (" \r\n ") – ( hexadecimal 0x000d ), ( hexadecimal 0x000a ). При этом возвращаемая строка эти символы не включает.

В любом случае речь идет о получении символьной информации. Символьная информация достаточно просто извлекается из входного потока. Однако это не самая большая составляющая общего объема обрабатываемой информации. Как правило, содержимое входного потока приходится приводить к одному из базовых типов.

В .NET FCL реализован процесс преобразования информации в рамках Общей Системы Типов (CTS).

.NET Framework Class Library включает класс System.Convert, в котором реализовано множество функций-членов, предназначенных для выполнения ЗАДАЧИ ПРЕОБРАЗОВАНИЯ ЗНАЧЕНИЙ ОДНОГО базового ТИПА В ЗНАЧЕНИЯ ДРУГОГО базового ТИПА. В частности, в этом классе содержится множество функций (по нескольку функций на каждый базовый тип), обеспечивающих попытку преобразования символьных строк в значения базовых типов.

Кроме того, множество классов, входящих в CTS и FCL, располагают вариантами функции Parse(), основное назначение которой – ПОПЫТКА преобразования строк символов (в частности, получаемых в результате выполнения методов консольного ввода) в значения соответствующих типов.

При обсуждении функций преобразования неслучайно употребляется слово "попытка". Не каждая строка символов может быть преобразована к определенному базовому типу. Для успешного преобразования предполагается, что символьная строка содержит символьное представление значения в некотором общепринятом формате в соответствии с соответствующей существующей в операционной системе настройкой языковых параметров, представления чисел, времени и дат. С аналогичной ситуацией мы уже сталкивались при обсуждении понятия литералов. В случае успешного преобразования функции возвращают результат преобразования в виде значения соответствующего типа.

Если же значение одного типа не может быть преобразовано к значению другого типа, преобразующая функция ВЫРАБАТЫВАЕТ ИСКЛЮЧЕНИЕ, с помощью которого CLR (то есть среда выполнения!) уведомляется о неудачной попытке преобразования.

Файловый ввод/вывод

FileMode enumeration:

описывает, каким образом операционная система должна открывать файл.

Имя члена Описание
Append Открывается существующий файл и выполняется поиск конца файла или же создается новый файл. FileMode.Append можно использовать только вместе с FileAccess.Write. Любая попытка чтения заканчивается неудачей и создает исключение ArgumentException
Create Описывает, что операционная система должна создавать новый файл. Если файл уже существует, он будет переписан. Для этого требуется FileIOPermissionAccess.Write и FileIOPermissionAccess.Append. System.IO.FileMode.Create эквивалентно следующему запросу: если файл не существует, использовать CreateNew ; в противном случае использовать Truncate
CreateNew Описывает, что операционная система должна создать новый файл. Для этого требуется FileIOPermissionAccess.Write. Если файл уже существует, создается исключение IOException
Open Описывает, что операционная система должна открыть существующий файл. Возможность открыть данный файл зависит от значения, задаваемого FileAccess. Если данный файл не существует, создается исключение System.IO.FileNotFoundException
OpenOrCreate Указывает, что операционная система должна открыть файл, если он существует, в противном случае должен быть создан новый файл. Если файл открыт с помощью FileAccess.Read, требуется FileIOPermissionAccess.Read. Если файл имеет доступ FileAccess.ReadWrite и данный файл существует, требуется FileIOPermissionAccess.Write. Если файл имеет доступ FileAccess.ReadWrite и файл не существует, в дополнение к Read и Write требуется FileIOPermissionAccess.Append
Truncate Описывает, что операционная система должна открыть существующий файл. После открытия должно быть выполнено усечение файла таким образом, чтобы его размер стал равен нулю. Для этого требуется FileIOPermissionAccess.Write. Попытка чтения из файла, открытого с помощью Truncate, вызывает исключение

FileAccess enumerations:

Члены перечисления Описание
Read Доступ к файлу для чтения. Данные могут быть прочитаны из файла. Для обеспечения возможностей чтения/записи может комбинироваться со значением Write
ReadWrite Доступ к файлу для чтения/записи
Write Доступ к файлу для записи. Данные могут быть записаны в файл. Для обеспечения возможностей чтения/записи может комбинироваться со значением Read
using System;
 using System.IO;

namespace fstream00
 {
 class Class1
 {
 static	string[] str = {
 "1234567890",
 "qwertyuiop",
 "asdfghjkl",
 "zxcvbnm", 	};

static void Main(string[] args)
 {
 int i;
 // Полное имя файла.
 string filename = @"D:\Users\WORK\Cs\fstream00\test.txt";
 string xLine = "";
 char[] buff = new char[128];
 for (i = 0; i < 128; i++) buff[i] = (char)25;
 // Запись в файл.
 FileStream fstr = new FileStream(filename,
 FileMode.Create,
 FileAccess.Write);
 BufferedStream buffStream = new BufferedStream(fstr);
 StreamWriter streamWr = new StreamWriter(buffStream);
 for (i = 0; i < str.Length; i++)
  {
 streamWr.WriteLine(str[i]);	
 }

streamWr.Flush();
 streamWr.Close();

Console.WriteLine("–––––––––––––––––––––––––––––––––––––––––––");

fstr = new FileStream(filename,
 FileMode.Open,
 FileAccess.Read);

StreamReader streamRd = new StreamReader(fstr);
 for ( ; xLine != null; )
 {
 xLine = streamRd.ReadLine();
 Console.WriteLine(xLine);	
 }


Console.WriteLine("––––––––––––––––––––––––––––––––––––––––––––");
 fstr.Seek(0, SeekOrigin.Begin);
 streamRd.Read(buff,0,10);
 Console.WriteLine(new string(buff));
 Console.WriteLine("1––––––––––––––––––––––––––––––––––––––––––");

streamRd.Read(buff,0,20);
 Console.WriteLine(new string(buff));
 Console.WriteLine("2––––––––––––––––––––––––––––––––––––––––––");
Console.WriteLine(streamRd.Read(buff,0,15));
 i = (int)fstr.Seek(–20, SeekOrigin.Current);
 Console.WriteLine(streamRd.ReadLine());

Console.WriteLine("3––––––––––––––––––––––––––––––––––––––––––");
 }
 }
 }
Листинг 11.1.

Пример перенаправления потоков. В файл можно записать информацию, используя привычные классы и методы!

using System;
 using System.Collections.Generic;
 using System.Text;
 using System.IO;

namespace OutFile
 {
 class Program
 {

static void Main(string[] args)
 {
 string buff;

FileStream outFstr, inFstr; // Ссылки на файловые потоки.

 // Ссылка на выходной поток. Свойства и методы,
 // которые обеспечивают запись в...
 StreamWriter swr;

 // Ссылка на входной поток. Свойства и методы,
 // которые обеспечивают чтение из...
 StreamReader sr;  

 // Класс Console –  средство управления ПРЕДОПРЕДЕЛЕННЫМ потоком. 
 // Сохранили стандартный выходной поток,
 // связанный с окошком консольного приложения. 
TextWriter twrConsole = Console.Out;

 // Сохранили стандартный входной поток, связанный с буфером клавиатуры.
 TextReader trConsole = Console.In;

inFstr = new FileStream
               (@"F:\Users\Work\readme.txt", FileMode.Open, FileAccess.Read);
 sr = new StreamReader(inFstr); // Входной поток, связанный с файлом. 

outFstr = new FileStream
               (@"F:\Users\Work\txt.txt", FileMode.Create, FileAccess.Write);
 swr = new StreamWriter(outFstr); // Выходной поток, связанный с файлом.
 // А вот мы перенастроили предопределенный входной поток.
 // Он теперь связан не с буфером клавиатуры, а с файлом, открытым для чтения.
 Console.SetIn(sr);
 Console.SetOut(swr);
     
while (true)
 {
 // Но поинтересоваться в предопределенном потоке отностительно
 // конца файла невозможно.
 // Такого для предопределенных потоков просто не предусмотрено. 
if (sr.EndOfStream) break;

 // А вот читать - можно.
 buff = Console.ReadLine();
 Console.WriteLine(buff);           
    
 }
Console.SetOut(twrConsole);
 Console.WriteLine("12345");            
Console.SetOut(swr);
 Console.WriteLine("12345");
 Console.SetOut(twrConsole);
 Console.WriteLine("67890");
 Console.SetOut(swr);
 Console.WriteLine("67890");

sr.Close();
 inFstr.Close();
 swr.Close();
 outFstr.Close();
 }
 }
 }
Листинг 11.2.
kewezok kewezok
kewezok kewezok
Елена Шляхт
Елена Шляхт
Объясните плиз в чем отличие а++ от ++а
Почему результат разный?
int a=0, b=0;
Console.WriteLine(a++); //0
Console.WriteLine(++b); //1
a++;
++b;
Console.WriteLine(a); //2
Console.WriteLine(b); //2