68972

Файли. Робота з файлами. Файловий ввід-вивід

Лекция

Информатика, кибернетика и программирование

Не дивлячись на те що система введення-виведення мови C++ в цілому є єдиним механізмом, система файлового введення-виведення має свої особливості. Частково це пояснюється тим, що на практиці найчастіше використовуються файли на жорсткому диску, можливості яких значно відрізняються від всіх інших пристроїв.

Украинкский

2014-09-28

58 KB

7 чел.

Лекція № 17

Тема: Файли. Робота з файлами.

План

  1.  Файловий ввід-вивід
  2.  Відкриття і закриття потоку
  3.  Читання і запис текстових файлів
  4.  Безформатне і бінарне введення-виведення

Файловий ввід-вивід

Не дивлячись на те що система введення-виведення мови C++ в цілому є  єдиним механізмом, система файлового введення-виведення має свої особливості. Частково це пояснюється тим, що на практиці найчастіше використовуються файли на жорсткому диску, можливості яких значно відрізняються від всіх інших пристроїв. Проте слід мати на увазі, що файлове уведення-виведення є лише частиною загальної системи введення-виведення, і велика частина матеріалу, викладеного в розділі, відноситься до потоків, які можуть бути пов'язані з іншими пристроями.

Для реалізації файлового введення-виведення в програму слід включити заголовок <fstream>. У нім визначені деякі класи, зокрема, ifstream, ofstream і f stream. Ці класи є похідними від класів istream, ostream і ios-tream відповідно. Слід пам'ятати, що класи istream, ostream і iostream, у свою чергу, є похідними від класу ios, розглянутого в попередньому розділі. Файлова система використовує також клас filebuf, що надає низкоуровневые засоби управління файловим потоком. Зазвичай клас filebuf непосредственно не застосовується, проте він є складовою частиною інших класів.

 

Відкриття і закриття файлу

У мові C++ відкриття файлу означає його пов'язання з потоком. Отже, спочатку необхідно отримати потік. Існують три види потоків: введення, виведення і введення-виведення. Для того, щоб створити потік введення, необхідно оголосити потік, що є об'єктом класу ifstream Для генерації потоку виведення необхідно оголосити потік, що є об'єктом класу ofstream. Потоки, здійснююче введення і виведення, оголошуються як об'єкти класу fstream Наприклад, в наступному фрагменті створюється потік введення, потік виведення і потік введення-виведення.

ifstream in;  // Введення

ofstream out; // Виведення

fstream io;   // Введення і виведення

Створений потік можна пов'язати з файлом за допомогою функції ореn(). Ця функція є членом кожного з трьох потокових класів. Її прототипи в кожному класі показані нижче.

ifstream::open(const char *filename, ios::openmode

mode = ios::in);

ifstream: : open (const char  * filename,   

ios : : openmode mode = ios::out | ios::trunc);

ifstream::open(const  char  * filename,   

ios::openmode mode = ios::in   |   ios::out);

Тут параметр filename задає ім'я файлу. Він може містити шлях до цього файлу. Значення параметра mode визначає спосіб відкриття файлу. Цей параметр може приймати наступні значення, описані у функції openmode.

ios::арр ios::ate ios::binary ios::in ios::out ios::trunc

Дані значення можна комбінувати за допомогою логічної операції "АБО". Якщо задається значення ios:: арр, всі результати дописуються в кінець файлу, що риється для виведення. Якщо вказано значення ios: :ate, при відкритті виконується позов кінця файлу. Не дивлячись на це, запис проводиться в будь-яке місце файлу. Якщо задається значення ios:: in, файл відкривається для введення, а якщо ios:: out —  виведення.

Значення ios::binary дозволяє відкрити файл в бінарному режимі. По замовчуванню всі файли відкриваються в текстовому режимі. В цьому випадку проводиться перетворення деяких символів, наприклад, ескейп-послідовність "повернення каретки" і "прогін паперу" перетвориться в символ переходу на новий рядок. Проте, файл відкритий в бінарному режимі, перетворення символів не проводиться. Слід пам'ятати, що будь-який файл можна відкрити як в текстовому, так і в бінарному режимі. Єдина відмінність між ними полягає в тому, проводиться перетворення символів чи ні.

Значення ios::trunc сигналізує, що попередній вміст існуючого файлу з тим же ім'ям буде знищений, а довжина файлу зменшена до нуля. При відкритті потоку виведення за допомогою класу ofstream вміст будь-якого існуючого файлу з вказаним ім'ям стирається. В наступному фрагменті відкривається текстовий файл для виведення.

 

ofstream out; out.open( "test", ios::out);

 

Проте функція open() рідко застосовується для відкриття файлів, оскільки для кожного типу потоку параметр mode має значення, задані за умовчанням. Прототипи функції open демонструють, що значення параметра mode, задане по замовчуванню, в класі ifstream рівне ios::in, в класі ofstream – ios::out | ios: :trunc, а в класі fstream — ios: :in | ios: :out. По цій причині попередній виклик функції open зазвичай записують так:

out.open(" test"); // Текстовий файл для виведення

Якщо потік застосовується в логічних виразах, у разі відмови функції open() йому привласнюється значення false. Таким чином, перед використанням файлу слід переконатися, що він успішно відкритий. Для цього можна скористатися наступними операторами.

if(!mystream)   {

cout «   "Неможливо відкрити  файл.\n";

// Обробка помилки

}

Однак частіше за все функцію ореn() не застосовують, оскільки класи ifstream, ofstream і fstream містять конструктори, що автоматично відкривають файл. Параметри цих конструкторів приймають ті ж значення за умовчанням, що і функція ореn(). З цієї причини файли зазвичай відкривають таким чином.

ifstream mystream( "myfile");   //  Відкриття файлу для  введення

Якщо з якої-небудь причини файл відкрити не вдалося, пов'язаному з ним потоку присвоюється значення false. Отже, якщо якийсь конструктор викликає функцію open(), слід переконатися, що файл дійсно відкритий, перевіривши значення потоку.

Щоб перевірити, чи відкритий файл, можна викликати функцію is_open(), яка є членом класу fstream, ifstream і ofstream. Вона має наступний прототип.

bool is_open();

Якщо потік пов'язаний з відкритим файлом, ця функція повертає значення true, інакше вона повертає значення false. Наприклад, наступний фрагмент перевіряє, чи відкритий файл, пов'язаний з потоком mystream.

if(!mystream.is_open())  {

cout «   "Файл не  відкритий.\n";

//   ...

}

Щоб закрити файл, слід викликати функцію close(). Наприклад, щоб закрити файл, пов'язаний з потоком mystream, можна застосувати наступний оператор

mystream.close() ;

Функція close () не має параметрів і не повертає ніяких значень.

Читання і запис текстових файлів

Читання і запис текстових файлів здійснюються дуже легко. Для цього достатньо застосувати операторів "<<" і ">>", як це зазвичай робиться для консольного введення-виведення, тільки замість потоків cin і cout необхідно підставити потік, що зв’язаний з файлом. Наприклад, наступна програма створює короткий файл, який містить назву предмету і його вартість.

#include <iostream>

#include <fstream>

using namespace std;

int main() {

ofstream out("INVNTRY"); // Текстовий файл для виведення.

if(!out){

cout « "Неможливо відкрити файл INVENTORY.\n";

return 1;

}

out << "Радіоприймачі " « 39.95 « endl;

out « "Тостери " « 19.95 « endl;

out « "Міксери " « 24.80 « endl;

out.close();

return 0;

}

Програма, приведена нижче, прочитує файл, створений попередньою програмою, і виводить його вміст на екран.

#include <iostream>

#include <fstream>

using namespace std;

int main () {

ifstream in("INVNTRY");   //  Введення

if(!in)  {

cout <<   "Неможливо відкрити  файл INVENTORY. \n" ;

return  1;

}

char item[20];

float cost;

in »  item »    cost;

cout «  item «   "   "  «  cost «   "\n"

in » item >> cost;

cout «  item «   "   "   «  cost «   "\n"

in >> item » cost;

cout «  item «   "   "   « cost «   "\n"

in.close() ;

return 0;

}

 

Читання і запис файлів за допомогою операторів "«" і "»" нагадує використання функцій fprintf() і fscanf() з мови С. Формат записів у файлі нічим не відрізняється від формату виведення на екран.

Прочитуючи файли за допомогою оператора ">>", майте на увазі, що деякі символи при введенні трансформуються. Наприклад, роздільники ігноруються. Щоб відмінити перетворення символів при читанні, файл слід відкрити в бинарному режимі і застосувати функції, описані в наступному розділі.

Якщо при введенні досягається кінець файлу, потоку, пов'язаному з файлом, присвоюється значення false. (Ця ситуація ілюструється в наступному розділі.)

 

Безформатне і бінарне уведення-виведення

Отже, читання і запис форматованих текстових файлів не викликає ніяких труднощів, хоча це не найефективніший спосіб роботи з файлами. Окрім цього іноді виникає необхідність зберігати безформатні дані, а не текст. Розглянемо функції, призначені для роботи з такими даними.

Виконуючи з файлом бінарні операції, слід переконатися, що він відкритий в режимі ios::binary. Безформатні дані можуть зберігатися і в текстовому файлі, але в цьому випадку при читанні деякі символи будуть перетворені. Бінарні файлу застосовуються саме для того, щоб цього уникнути.

Порівняння символів і байтів

При вивченні безформатного введення-виведення необхідно враховувати наступне. Багато років уведення-виведення в мовах С і C++ був байтовим (byte oriented). Це відбувалося тому, що символ (char) є еквівалентом байта, і потоки виведення були символьними. Проте з появою розширених символів (wchar_t і пов'язаних з ними потоків систему введення-виведення мови C++ не можна назвати байтовою. Тепер її слід називати символьною (character oriented). Зрозуміло, потоки звичайних символів (char) залишаються байтовими, особливо при обробці нетекстових даних. Проте еквівалентність понять "символ" і "байт" більше не гарантуєте

Ми використовуємо тільки символьні (тобто байтові) потоки, оскільки вони найширше поширені. Вони забезпечують простішу обробку безформатних файлів, оскільки символьні потоки збергіають однозначну відповідність між символами і байтами.

Функції put() і get()

Один із способів читання і запису безформатних файлів заснований на використанні функцій put () і get (). Ці функції оперують символами. Точніше кажучи, функція get () прочитує символ, а функція put () — записує його. Зрозуміло, якщо файл відкритий в бінарному режимі, то при прочитуванні символу (а не розширення символу), ці функції прочитують і записують байти.

Функція get () має декілька форм, проте найчастіше використовується її наступна версія.

istream &get(char &ch)

ostream &put(char ch)

Функція get () прочитує окремий символ з потоку і записує його в змінну ch. Крім того, функція get () повертає посилання на потік. Функція put() записує змінну ch в потік і повертає посилання на потік

Наступна програма відображає на екрані вміст будь-якого файлу (як текстового, так і бінарного). Для зчитування даних вона використовує функцію get ().

#include <iostream>

#include <fstream>

using namespace  std;

int main(int argc,   char  *argv[])

{

char  ch;

if(argc!=2){

cout << "виклик: PR <ім'я файла>\n";

return 1;

}

ifstream in(argv[l], ios::in | ios::binary);

if(!in){

cout « "Неможливо відкрити файл.";

return 1;

}

while(in)  {   //  Якщо досягнутий кінець файлу

//  значення  об'єкту  in рівне  false.

in.get(ch);

if(in)  cout  «   ch;

}

return 0;

}

Як указувалося в попередньому розділі, після досягнення кінця файлу потік, связанный з цим файлом, приймає значення false. Отже, рано чи пізно об'єкт in прийме значення false, і виконання циклу while припиниться.

Приведений вище цикл можна записати коротше.

while(in.get(ch)) cout «  ch;

Цей фрагмент є правильним, оскільки функція get () повертає ссылку на потік in, який прийме значення false при виявленні кінця файлу.

Функції read() і write()

Блоки бінарних даних можна прочитувати за допомогою функцій read() i  write(). Їх прототипи виглядають таким чином.

istream &read(char  *buf,   streamsize num);

istream &write(const char  *buf,   streamsize num);

Функція read прочитує num символів з потоку і записує їх в буфер, на який посилається покажчик buf. Функція write записує num символів в потік прочитуючи їх з буфера, на який посилається покажчик buf. Тип streamsize визначений в бібліотеці як різновид типу int. Він дозволяє зберігати максимальну кількість символів, які можуть перетворюватися при виконанні операцій введення-виведення.


 

А также другие работы, которые могут Вас заинтересовать

40380. ПСИХОТЕРАПИЯ 41 KB
  Психотерапия в широком смысле охватывает всю область общения врача и больной. Психотерапия имеет целью устранить проявления болезни изменить отношение больного к своему состоянию самому себе и окружающему. Выделяют следующие основные методы психотерапии: 1 рациональная психотерапия; 2 суггестивная психотерапия включающая внушение наяву в состоянии гипнотического сна и самовнушение аутосуггестия; 3 коллективная групповая психотерапия семейная поведенческая игровая имаготерапия психоэстетотерапия и т.
40381. РЕАКТИВНЫЕ СОСТОЯНИЯ И ПСИХОЗЫ 49 KB
  Реактивные состояния легче возникают у психопатических личностей а также у лиц ослабленных инфекциями тяжелыми соматиче скими заболеваниями интоксикациями черепномозговыми травмами сосудистыми заболеваниями длительной бессонницей тяжелыми авита минозами и др. Реактивные состояния и психозы подразделяются на: 1 аффективношоковые психогенные реакции; 2 депрессивные психогенные реакции реактивная депрессия; 3 реактивные пси хогенные бредовые психозы; 4 истерические психотические реакции или истерические психозы. В большинстве...
40383. СИНДРОМ СВЕРХЦЕННЫХ ИДЕЙ 23 KB
  Сверхценные идеи сопровождаются выраженным аффективным напряжением. Сверхценные идеи отличаются от бреда толкования интерпретативного тем что в их основе реальные факты и события а источники интерпретативного бреда целиком ошибочные неправильные умозаключения. Сверхценные идеи с течением времени при определенных условиях блекнут и исчезают а бредовые имеют тенденцию к дальнейшему развитию. Сверхценные идеи нередко сопутствуют депрессиям и бывают при этом тесно связаны с бредом самообвинения.
40384. Психические нарушения при сосудистых поражениях головного мозга. Расстройства возраста обратного развития 51 KB
  Все психические нарушения при сосудистых поражениях головного мозга не выходят за рамки психоорганического синдрома. сосудистая амнестический синдром органический бредовый синдром органический галлюциноз органическое кататоническое расстройство нарушения настроения органической природы синдром тревоги органического характера органические диссоциативные расстройства астенические расстройства расстройства личности вследствие органического поражения мозга и другие более редко встречаемые нарушения. Каждому этапу развития заболевания...
40385. Судебная психиатрия 57 KB
  поэтому при проведении судебнопсихиатрической экспертизы нередко привлекаются специалисты узких областей психиатрии. О психиатрической помощи и гарантиях прав граждан при ее оказании ; Инструкция о производстве судебнопсихиатрической экспертизы № 1091 1470 утверждена Министерством здравоохранения СССР и согласована с Прокуратурой СССР Верховным судом СССР Министерством внутренних дел СССР 03. Правовые и организационные аспекты судебнопсихиатрической экспертизы Вопросы судебнопсихиатрической экспертизы регламентированы уголовным и...
40386. АФФЕКТИВНЫЕ СИНДРОМЫ 49 KB
  До настоящего времени многочисленные исследования посвященные поиску предикторов суицидального поведения както психопатологических личностных социальнодемографических соматических и прочих не позволили выдвинуть достаточно надежных для практики критериев предсказания суицида. Наиболее весомые клинические критерии имели прямую корреляцию выше 05 лишь со степенью серьезности суицидального намерения что говорит об опосредованном значении психопатологических критериев. Результаты подобных исследований в области предсказания суицидального...
40387. ОПРЕДЕЛЕНИЕ ЛЕГИРУЮЩИХ ПРИМЕСЕЙ В СТАЛИ МЕТОДОМ ЭМИССИОННОГО АТОМНОГО СПЕКТРАЛЬНОГО АНАЛИЗА 47.72 KB
  Изучить основы метода определения химического состава сплавов методом эмиссионного спектрального анализа. Провести качественный и полуколичественный анализ легированных сталей по элементам Cr, Mn, Ni с помощью стилоскопа СЛП-1
40388. Труксал (хлорпротиксен) при лечении больных в общесоматической сети 47 KB
  Сеченова Потребность в нейролептиках у больных общесоматического стационара достаточно велика. Смулевич свидетельствуют что около 6 больных госпитализированных в крупную многопрофильную больницу нуждаются в назначении нейролептических медикаментозных средств. Предпочтительны нейролептические средства и при широком круге психических расстройств у больных с явлениями зависимости от психоактивных веществ алкоголизм наркомании и т.