Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Потоки й файли



Описаний вище механізм введення-виведення можна використати не тільки для консолі, але й для файлів як у текстовому, так і в бінарних режимах. Для реалізації файлового введення-виведення необхідно включити в програму заголовок <fsream>. У ньому визначено кілька потокових класів: ifstream (для створення потоку введення), ofstream (для потоку виведення) і fsream (для потоків, що одночасно реалізують введення й виведення). Перед початком роботи з файлом необхідно створити потік за допомогою, наприклад, однієї з наступних інструкцій:

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

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

fstream io; //введення й виведення

Потім із створеним потоком зв'язується файл. Для цього використається функція open() із прототипом:

void stream1:: open("file1", ios:in);

– зв'язування файлу по імені file1 з потоком введення у файл, ios:in – значення, що задає режим відкриття файлу для введення. Інші режими роботи з файлами задаються за допомогою значень: ios:out (відкриття файлу для виведення), ios:app (режим додавання в кінець файлу), ios:binary (двійковий режим),.

Використати функцію open() для відкриття файлу не обов'язково, тому що в класах ifstream, ofstream і fstream є конструктори, які відкривають файл автоматично. Відкрити файл можна в таким чином:

ifstream stream1 ("file1");

У цій функції другий параметр відсутній, оскільки він за умовчанням буде мати те значення (ios:in), що відповідає типу потоку, що відкривається.

Для закриття файлу використається функція close(). Наприклад, щоб закрити файл, пов'язаний з потоком stream1, потрібно записати:

stream1.close();

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

8.1.3. Текстові файли. Форматоване введення-виведення

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

Пример запису рядка й числа в текстовий файл:

#include <iostream>

#include <fstream>

using namespace std;

int main(){

ofstream fout("test.txt"); //Створення файлу для виведення

if(!fout) { //Якщо не вийшло створення файлу

cout << " Can't open file\n";

return 1; }

fout << "Record to file\n"<<100<< endl; //Запис у файл

fout.close();//Закриття файлу

return 0; }

У результаті роботи цього коду в поточній директорії програми буде створений файл test.txt, що містить наступний текст:

Record to file

Приклад введення рядків із клавіатури й запису в файл. Програма завершується при введенні символу # як першого символу рядка (у цьому й наступному прикладах директиви на підключення бібліотек iostream і fstream опущені).

int main(){

ofstream fout("test.txt");

if(!fout) {

cout << " Can't open file\n";

return 1; }

char str[80];

cout << "Enter string/For ending enter #\n";

do {cout << ": ";

cin >> str;

fout << str << endl; //У потік виведення записати str

} while (*str!='#'); //Поки не введений символ #

fout.close();

return 0; }

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

ofstream fout("test.txt", ios::app);

Приклад зчитування текстового файлу й виведення на екран:

int main(){

ifstream fin("test.txt"); //Відкриття файлу

if(!fin) { //Якщо файл не знайдений

cout << " Can't open file\n";

return 1;}

char ch;

fin.unsetf(ios::skipws); //Не пропускати пробіли

for (;;){

fin >> ch; //Запис символу з файлу в змінну ch

if (fin.eof()) break; //Якщо досягнуто кінець файлу

cout << ch; /*Виведення символу на екран*/ }

fin.close(); //Закриття файлу

return 0; }

Приклад копіювання файлів. Програма копіює файл file1 у файл file2 і підраховує число скопійованих символів.

int main(){

ifstream fin("file1.dat", ios::in);//Відкрити для введення

ofstream fout("file2.dat", ios::out);//Відкрити для виведення

if(!fin) { cout << "Can't open file1\n";

return 1; }

if(!fout) {cout << "Can't open file2\n";

return 1; }

char ch;

unsigned count = 0;

fin.unsetf(ios::skipws); //Не пропускати пробіли

for (;;){fin >> ch;

if (fin.eof()) break;

fout << ch;

count++; }

cout << "Number of copied bytes: " << count << '\n';

fin.close();

fout.close();

return 0; }

8.1.4. Неформатоване двійкове введення-виведення

Текстові файли зручні для сприйняття, однак більш гнучку структуру мають двійкові (бінарні) файли. Такі файли призначені для неформатованого введення-виведення, що здійснюється за допомогою функцій: put(), get(), getline(), а також write() і read().

1. Побайтове введення-виведення. Функція get() зчитує один байт із потоку й передає його значення аргументу s, а функція put()записує символ s у потік і повертає посилання на потік:

istream &get (char &s);

ostream &put (char s);

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

istream &read (char *buf, num);

ostream &write (const char *buf, num);

3. Рядкове введення. Функція getline() зчитує з потоку символи й передає їх у буфер buf доти, поки не буде зчитано (num-1) символів, або не зустрінеться символ нового рядка:

istream &getline (char *buf, num);

Відкриття й закриття бінарних файлів здійснюється точно так само, як і текстових файлів.

Приклад зчитування двійкового файлу:

int main(){

char ch;

ifstream in("test", ios::in | ios::binary);

if(!in) {cout << "Can't open file\n";

return 1; }

while(!in.eof()) {in.get(ch);

cout << ch; }

in.close();

return 0; }

Приклад запису із клавіатури у двійковий файл. Введення символів у файл припиняється при натисканні клавіші #.

int main(){

char ch;

ofstream out("test", ios::out | ios::binary);

if(!out) {cout << "Can't open file\n";

return 1; }

cout<<"For ending input #\n";

do {cout << ": ";

cin.get(ch);

out.put(ch);

} while (ch!='#');

out.close();

return 0; }

Приклад відкриття й зчитування текстового файлу. Можливе відкриття текстового файлу в бінарному режимі. Цей приклад ілюструє, як функції, призначені для роботи із двійковими файлами, можуть бути використані для операцій з текстовими файлами.

int main () {

char c, str[256];

ifstream is;

cout << "Enter the name of an existing file: ";

cin.get (str,256);

is.open (str); // Відкрити файл

while (is.good()){ //Почати цикл, якщо немає помилок

c = is.get(); //Взяти символ з файлу

cout << c; } //Вивести символ на екран

is.close();

return 0; }

Функція good() повертає true, якщо відсутні помилки при відкритті файлу.

Приклад блокового введення-виведення. Запис файлу в пам'ять.

int main () { int length;

char * buffer;

ifstream is;

is.open ("test", ios::binary);

is.seekg (0, ios::end); //Визначення

length = is.tellg(); //довжини файлу

is.seekg (0, ios::beg);

buffer = new char [length];

is.read (buffer,length); //Читання даних блоку

is.close();

cout.write (buffer,length);

return 0; }

8.1.5. Файли довільного доступу

Система введення-виведення С++ дозволяє створювати файли, що складаються із записів фіксованої довжини. Це забезпечує легкий пошук інформації при довільному доступі до файлу. Довільний доступ реалізується за допомогою потокових функцій введення й виведення: seekg() і seekp().

Для пошуку запису задається початок відліку (прапорці ios::beg, ios::end або ios::cur) і зсув покажчика відносно початку відліку. Наприклад, функція seekg(120,ios::beg) установлює покажчик зчитування файлу в позицію, що відстоїть на 120 байтів від початку файлу. А функція seekp(8,ios::end) установлює покажчик запису в позицію, що відстоїть на 8 байт від кінця файлу.

Файли довільного доступу повинні відкриватися в режимі операцій для двійкових файлів. Визначити поточну позицію кожного із двох покажчиків можна за допомогою функцій tellg() (повертає позицію покажчика зчитування) tellp() (повертає позицію покажчика запису).

Приклад. Заміна символу в зазначеній позиції.

int main () {

char * buffer;

fstream in;

in.open ("test.txt", ios::in|ios::out|ios::binary);

in.seekp(2,ios::beg); //Установка покажчика запису

in.put('r'); //Заміна символу

in.close();

return 0; }

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

char ch;

in.unsetf(ios::skipws); //Не пропускати пробіли

in.seekg(length,ios::beg);//Зчитування, починаючи з 2-го рядка

for (;;){in >> ch;

//Припинення зчитування наступних рядків

if (in.tellg()>2*length) break;

cout << ch; }

8.2. Постановка задачі

Відповідно до свого варіанта завдання скласти програму, у якій відкриваються необхідні файли й виконуються операції над ними.

8.3. Варіанти завдань

1. Записати у файл квадратну матрицю цілих випадкових чисел, користуючись форматним виведенням. Занести в буфер і вивести на екран другий рядок матриці.

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

3. Записати у файл квадратну нижню трикутну матрицю випадкових чисел, користуючись форматним виведенням. Занести в буфер і вивести на екран перший рядок матриці.

4. Записати у файл одновимірний масив випадкових чисел. Зробити дві копії файлу. В одній з копій розташувати елементи масиву у зворотному порядку.

5. Записати у файл таблицю з полями: місяць, число днів у місяці (усього 12 записів). Вивести таблицю на екран. Видалити в таблиці місяці із серпня по грудень. Сформувати файл із новою таблицею.

6. Записати у файл таблицю з полями: місяць, число днів у місяці (усього 12 записів). Вивести таблицю на екран. Видалити в таблиці запису із числом днів 31. Сформувати новий файл.

7. Записати у файл таблицю з полями: місяць, число днів у місяці (усього 12 записів). Вивести таблицю на екран. Видалити в таблиці літні місяці. Сформувати файл із новою таблицею.

8. Записати у файл рядок з декількох слів. Підрахувати кількість слів і букв 'е'.

9. Записати у файл рядок. Скопіювати в буфер фрагмент рядка від початку до першого символу 'а'. Вивести фрагмент на екран.

10. Записати у файл рядок. Скопіювати в буфер фрагмент рядка від початку до першого символу 'е' у другому слові. Вивести фрагмент на екран.

11. Записати у файл рядок. Скопіювати в буфер останні два слова. Вивести вміст буфера на екран.

12. Записати у файл рядок. Скопіювати в буфер перше й останнє слово. Вивести вміст буфера на екран.

13. Записати у файл рядок. Скопіювати в буфер слова у зворотному порядку. Вивести вміст буфера на екран.

14. Записати у файл одновимірний масив цілих випадкових чисел, користуючись форматним виведенням. Перетворити елементи масиву від десяткової до шістнадцятеричної системи.

15. Записати у файл таблицю телефонів. Вивести таблицю на екран. Видалити в таблиці другий запис.

16. Записати у файл таблицю телефонів. Вивести таблицю на екран. Відкоригувати таблицю, замінивши номера АТС з 444 на 242.

17. Записати в файли file1 і file2 рядки. Додати до рядка file2 рядок з file1. Вивести вміст file2 на екран.

18. Вивести на екран вміст текстового файлу у зворотному порядку.

19. Попарно переставити символи в текстовому файлі (наприклад, 1234 - змінити на 2143).

20. Записати у файл цілі випадкові числа. Знайти суму всіх записаних чисел.

21. Написати програму копіювання файлу: перша половина – вихідний файл, друга половина він же у зворотному порядку. Читання відбувається блоками.

22. Написати програму копіювання файлу з видаленням зайвих пробілів.

23. Написати програму обчислення кількості символів переведення рядка у файлі.

24. Написати програму обчислення кількості символів у файлі. Читання відбувається блоками.

8.4. Методичні вказівки

В операціях з файлами довільного доступу використати режим двійкового введення-виведення.

8.5. Зміст звіту

1. Постановка завдання.

2. Код програми.

3. Скриншот з результатами роботи програми.

4. Пояснення принципів використання файлових потоків, операцій запису й зчитування даних.

Література

1. Г. Шилдт. С++. Базовый курс. 3-е изд. М: Вильямс, – 2005, 624 с.

2. Дж. Либерти. Освой самостоятельно С++. 5-е изд. М: Вильямс, – 2006, 784 с.

3. В.В. Подбельский. Язык Си++. М.: Финансы и статистика. – 2005, 560 с.

4. Т.А. Павловская. С/С++. Программирование на языке высокого уровня.
М., С.-Пб.: Питер, – 2004, 464 с.

5. Х. Дейтел, П. Дейтел. Как программировать на С++. М.: Бином, – 2000, 1152с.

6. Н. Культин. С/С++ в задачах и примерах. С.-Пб.: BHV. – 2005, 292 с.





Дата публикования: 2015-04-07; Прочитано: 1325 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.019 с)...