Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Methods_AP_LABS_II

.pdf
Скачиваний:
17
Добавлен:
17.03.2016
Размер:
1.05 Mб
Скачать

Виводить символ с у потік stream (записує у файл). У випадку успіху

повертає с, у випадку помилки - EOF.

int fputs(const char *s, FILE *stream)

Ввиводить рядок s у потік. У випадку успіху повертає ненегативне ціле,

у випадку помилки EOF.

Лістинг 6.1

#include <stdio.h> #include <stdlib.h> int main()

{

FILE *fp;

char buffer[256];

fp=fopen ("file.dat","r") ; //відкриваємо файл для

читання

 

if(!fp)

 

puts("Помилка відкриття файлу " ) else

 

{

 

while(fgets(buffer,255,fp)!=NULL)

//поки не

кінець

 

//файлу,

уводимо рядок

fputs(buffer, stdout) ;

//виводимо

на екран

 

fclose(fp);

 

}

return(0);

}

6.1.4 Виведення у файл

Найбільш поширеною функцією для виведення даних у файл є функція

fprintf() з наступним синтаксисом

int fprintf (FILE * stream, const char * format, ...)

з параметрами:

stream — вказівник на структуру FILE, отриманий при відкритті файлу.

format — форматна строка. Довільний рядок, що може містити специфікатори формату наступного вигляду

%[flags][width][.precision][length]specifier

Найважливішим є поле specifier, яке визначає тип та формат даних, що буде записано у файл (таблиця 6.3).

 

 

 

Таблиця 6.3

 

 

Поле specifier

 

 

 

 

 

Поле

 

Що буде виведено/прочитано

Приклад

specifier

 

 

 

 

 

 

 

c

 

Символ

А

 

 

 

 

d або i

 

Ціле число зі знаком

-234

 

 

 

 

f

 

Число з плаваючою точкою

34.32

 

 

 

 

s

 

Рядок С

Hello, World!

 

 

 

 

u

 

Ціле без знаку

123

 

 

 

 

Можливі значення інших полів є наступними (таблиці 6.4-6.7).

 

 

 

Таблиця 6.4

 

 

Поле flags

 

 

 

 

Поле flags

Опис

 

 

 

 

-

 

Вирівнювання вліво. За замовчуванням — вправо.

 

 

‘ ‘

Якщо знак не відображається, перед числом вставляється

 

 

пробіл.

 

 

 

 

0

 

Використати нулі замість пробілів при вирівнюванні вліво.

 

 

 

 

 

 

 

Таблиця 6.5

 

 

 

Поле width

 

 

 

 

Поле

 

 

Опис

width

 

 

 

 

 

 

 

число

 

Мінімальна кількість символів при виведенні значення. У випадку,

 

 

коли значення менше цього числа, результат доповнюється

 

 

пробілами.

 

 

 

 

‘ ‘

 

Якщо знак не відображається, перед числом вставляється пробіл.

 

 

 

 

 

 

 

Таблиця 6.6

 

 

 

Поле precision

 

 

 

Поле

 

Опис

.precision

 

 

 

 

.число

 

Для d, i, u — мінімальна кількість знаків, що буде виведено.

 

 

 

Якщо результат менше цього числа, поле вирівнюється нулями

 

 

 

зліва.

 

 

 

Для f — кількість знаків після точки.

 

 

 

Для s — максимальна кількість символів на виході.

 

 

 

 

 

 

 

Таблиця 6.7

 

 

 

Поле length

 

 

 

Поле

 

Опис

length

 

 

HАргумент інтерпретується як short int або unsigned short int (для i, d, u)

l

Аргумент інтерпретується як long int або unsigned long int (для i, d,

u)

LАргумент інтерпретується як long double (для f)

Уякості інших аргументів вказуються значення, що будуть виведені у відповідності до визначеного форматного рядку.

Приклад 6.1.

fprintf(stdout, “%3.1f”, 3.141) // вивести число PI з точністю 1 знак після коми, 3.1

Функція fprintf() повертає число символів, що було записано в файл.

Для читання інформації з файлу використовується функція з наступним

синтаксисом

int fscanf (FILE * stream, const char * format, ...)

зпараметрами:

stream — вказівник на структуру FILE, отриманий при відкритті файлу;

format — форматний рядок. Це довільний рядок, що може містити специфікатори формату виду [=%[*][width][modifiers]type=],

де

*

Дані будуть прочитані, але не будуть записані у відповідний

 

аргумент.

 

 

width

Максимальне число символів, що буде прочитано в поточній

 

операції.

 

 

modifiers

Те ж саме, що і length в fprintf()

 

 

type

Тип змінної, що буде прочитано. Те ж, що і specifier у fprintf().

 

Підтримуються c, d, f, s, u.

 

 

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

Лістинг 6.2. Прочитати з файла test.in 2 числа і записати їх суму в файл test.out.

#include <cstdio> #include <cstdlib>

int main()

{

using namespace std;

const char

*input = "test.in", *output = "test.out";

int a, b;

// Відкрити вхідний файл тільки для читання

FILE * in = fopen(input, "r"); if(!in)

{

perror(input); return -1;

}

//Прочитати 2 цілих числа if(fscanf(in, "%d %d", &a, &b) != 2)

{

printf("Не можу прочитати 2 цілих числа з файлу.\n"); return -2;

}

//Відкрити вихідний файл для запису

FILE * out = fopen(output, "w"); if(!out)

{

perror(output); return -3;

}

// Записати суму чисел у вихідний файл

if(fprintf(out, "%d", a + b) != 1) // не вірно так писати, т.я. fprintf()

повертає кількість записаних у файл символів

{

printf("Не можу записати суму у файл.\n"); return -4;

}

return 0;

}

Іноді виникає необхідність прочитати або записати у файл складний тип даних, для якого не визначено окремих символів форматування

(наприклад, структуру або масив). Для цього використовують бінарні файли та функції

size_t fread (void * ptr, size_t size, size_t count, FILE * stream); //

Читання з файлу

size_t fwrite (const void * ptr, size_t size, size_t count, FILE * stream); // Запис в файл

з наступними параметрами:

ptr — вказівник на масив, що буде прочитано з файлу або записано в файл;

size — розмір елементу масиву в байтах;

count — кількість елементів в масиві;

stream — вказівник на структуру FILE, отриманий при відкритті файлу.

Функція fread() (fwrite()) повертає кількість прочитаних (записаних)

елементів.

Приклад 6.2. Читання та запис заголовку бінарного файлу:

// Заголовок бінарного файлу struct {

int version; char name[20]; int data_size;

} header;

FILE* input = fopen(“test.hdf”, “r+b”)

// Прочитати заголовок з бінарного файлу if(!fread(&header, sizeof header, 1, input))

{

printf(“Не можу прочитати заголовок!”); exit(-1);

}

printf(“%d”, header.version); header.version++;

// Записати заголовок в бінарний файл if(!fwrite(&header, sizeof header, 1, input))

{

printf(“Не можу записати заголовок!”); exit(-2);

}

Для переміщення в рамках файлу (переміщення вказівника поточної позиції) використовується функція

int fseek (FILE * stream, long int offset, int origin)

з параметрами:

stream — вказівник на структуру FILE, отриманий при відкритті файлу;

offset — зсув відносно origin;

origin — позиція, відносно якої відраховується offset. Цей параметр

може приймати наступні значення:

SEEK_SET — початок файлу;

SEEK_CUR — поточна позиція в файлі;

SEEK_END — кінець файлу.

Функція повертає 0, якщо переміщення було успішним.

Наприклад,

fseek(f, 20, SEEK_SET); // Перемістити вказівник у файлі на 20

байт

Для того, щоб отримати поточну позицію у файлі використовують

функцію

long int ftell ( FILE * stream), де stream — вказівник на структуру

FILE, отриманий при відкритті файлу.

Наприклад, знайти розмір файлу можна наступним чином.

FILE* f = fopen(“test.txt”, “r”); fseek(f, 0, SEEK_END); long size = ftell(f);

Закрити файл можна за допомогою функції int fclose (FILE * stream) з

параметром stream — вказівник на FILE, що закривається.

Приклад:

fclose(in);

6.1.5 Потоки С++

Більш сучасний підхід для роботи з файлами з’явився у стандарті мови С++. В даному підході використовуються потоки введення/виведення

ifstream та ofstream.

Потоки ifstream та ofstream є класами (class). Більш докладно класи, їх властивості та основні принципи використання будуть розглядатися в учбовому курсі Програмування -2. Об’єктно-орієнтоване програмування.

Важливим є те, що операції та функції, які застосовні до стандартних потоків введення/виведення cin та cout (ЛР №1), можна використовувати також і при роботі з ifstream та ofstream.

Відкрити файл можна при створенні потоку:

ifstream ( const char * filename, mode);

ofstream ( const char * filename, mode);

або за допомогою відповідних їх методів

void open ( const char * filename, mode); void open ( const char * filename, mode);

з наступними параметрами:

filename — імя файлу, наприклад /etc/passwd;

mode — режим доступу до файлу.

У

стандарті С++ визначено наступні режими доступу до файлу

(таблиця 6.8):

 

Таблиця 6.8

 

Режими доступу

 

 

app

Доступ для додавання нової інформації. При виводі інформація

 

додається в кінець файлу.

 

 

ate

Перемістити вказівник файлу в кінець.

 

 

binary

Режим доступу до бінарного файлу.

 

 

in

Доступ для читання.

 

 

out

Доступ для запису.

 

 

trunc

Створити пустий файл для читання та запису. Якщо файл вже існує,

 

його вміст стирається.

 

 

Режими доступу можуть поєднуватися за допомогою оператора ‘або’

(|). Наприклад, режим ios::binary | ios::in визначає доступ тільки для читання

бінарного файлу.

Приклад 6.3

//Відкрити файл для читання ifstream in1(“test.in”);

//Те ж, з використанням функції open() ifstream in2;

in2.open(“test.in”);

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

ofstream out1(“test.out”);

// Те ж, з використанням функції open() ifstream out2;

out2.open(“test.out”);

Потоки ifstream та ofstream дозволяють використовувати модифікатори (endl, width, setf, hex) та методи (getline()), що визначені також і для потоків cin та cout (див. ЛР № 1). Наприклад, записати ціле число в шістнадцятковій системі в файл можна наступним чином.

ofstream o(“test.txt”); o << hex << 1234;

Лістинг 6.3.

// Прочитати 2 числа з вхідного файлу та записати в вихідний файл їх суму

#include <iostream> #include <fstream>

int main()

{

using namespace std;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]