1.1Открыть файл.
Прежде чем прочитать данные из файла или записать их туда, нужно открыть его. Иначе говоря, файл нужно инициализировать, связав его имя с переменной потока. Открыть файл можно, указав его имя при объявлении переменной потока. Например, оператор
ifstream inFile("Ages.DAT"); // Входной файл
объявляет переменную входного потока inFile, связывая ее с файлом по имени Ages .DAT. Имя файла может быть литеральной константой либо строковой переменной.
Кроме того, переменную входного потока можно объявить следующим образом:
ifstream inFile; а позднее применить функцию open для указания имени файла:
inFile.open("Ages.DAT");
Независимо от того, каким образом был открыт файл, переменную потока можно проверить с помощью следующего фрагмента кода.
if (inFile)
ProcessError()
//Открытие было безуспешным
С каждым файлом программы связан отдельный курсор (file window), который отмечает текущую позицию в файле. При открытии файла курсор указывает на первый компонент файла, как показано на рис. А.1.2.Поскольку компонентами файла являются символы, курсор перемещается с символа на символ.
Рис. А.1.2. При открытии существующего текстового файла курсор указывает на первую позицию
Если файл по какой-либо причине не удается открыть (например, входной файл в указанном каталоге не найден или нет свободного места на диске для выходного файла), то независимо от способа его открытия — конструктором или методом open() — потоковый объект принимает значение, равное нулю. Поэтому рекомендуется всегда проверять, чем завершилась попытка открытия файла, например:
Ifstream finp1(“data.txt");
if (!finp1)
{
cerr « "Файл data.txt не найден." « endl;
throw “Ошибка открытия файла “:
После того как файловый поток открыт, работа с ним чрезвычайно проста: с входным потоком можно обращаться так же, как со стандартным объектом cin, а с выходным — так же, как со стандартным объектом cout.
1.2Ввод символов.
Допустим, что в программе объявлена потоковая переменная inFile, с которой связано имя текстового файла, заданное строковой переменной fileName.
ifstream inFile(fileName);
Если этот файл используется для ввода, курсор указывает на компонент, который будет считан следующим. Следовательно, после открытия этого файла все готово для ввода первого компонента, как показано на рис. А.12. По мере считывания символов из текстового файла курсор перемещается от одного символа к другому. Ситуация, возникшая после ввода нескольких символов, проиллюстрирована на рис. А. 1.3.
Рис.A.I.3Курсор файла указывает на компонент, который будет считан следующим
W – последнее прочитанное значение X - значение, которое будет прочитано следующим
Оператор ввода >> и функции ввода, использующие входной поток сin и описанные ранее, также могут применяться для ввода данных из текстового файла. Допустим, в программе есть символьная переменная ch и переменная потока inFile.
Тогда операторы
inFile >> ch;
и
inFile.get();
означают следующее.
ch = значение, на которое указывает курсор файла Переместить курсор файла на следующий компонент
Иллюстрация работы этих операторов приведена на рис. А. 1.4.
После выполнения оператора inFile >> ch;
Puc.A.1.4. Эффект применения оператора inFile»ch к текстовому файлу inFile
При желании каждое из этих действий можно выполнить по отдельности. Текущее значение, считанное из файла, можно присвоить переменной ch, не перемещая курсора. Для этого нужно написать следующий фрагмент программы.
ch = inFile.peek ();
Текущее значение, на которое указывает курсор, можно проигнорировать и просто переместить курсор на п символов вперед с помощью оператора
inFile.ignore(n);
Курсор файла можно переместить непосредственно на позицию, следующую за очередным символом ch, либо просто на n символов, в зависимости от того, какая из ситуаций возникнет первой. Это действие осуществляется оператором
inFile.ignore(л, ch);
Функция peek позволяет определить, достигнут ли конец строки или файла. Например, цикл, приведенный ниже, выводит на экран строку из текстового файла.
while(inFile.peek() != '\n') //Цикл до конца строки
cout.put(inFile.get ());
Кроме того, следующие операторы позволяют вывести на экран весь текстовый файл.
while(inFile.peek() != EOF) //Цикл до конца файла
cout.put(inFile.get());
В заключение рассмотрим текстовый файл inFile, изображенный на рис. А. 14. Если переменная ch является символьной, то операторы, образующие приведенный ниже фрагмент программы, поочередно присвоят ей символы, считанные из текстового файла.
ifstream.inFile(fileName);
inFile >> ch; // ch = 'a'
inFile.get(ch); . // ch = 'b'
ch = inFile.get(); // ch = 'c'
ch =inFile.get(ch); // ch = 'e'
ch = inFile.peek() // ch ='f'
inFile.get(ch) ; // ch ='f'
inFile.get(ch); //ch = '\n
inFile.ignore(1) ; //пропустить символ конца файла
inFile.get(ch); //ошибка: попытка чтения
//за пределами файла
Кроме того, символы из текстового файла можно считывать целыми строками, используя функции getLine, get и read.
|