Ввод/вывод в стиле С удобнее использовать при форматированном выводе в программах, не использующих объектно-ориентированную технологию. Представление о вводе/выводе в стиле С необходимо иметь по причине существования множества программ, написанных на С, с которыми программисту поневоле приходится сталкиваться.
Для использования функций ввода/вывода в стиле С необходимо подключать к программе заголовочный файл <stdio.h> или <cstdio>. Практически также как в случае с потоковыми классами С++, при вводе/выводе в стиле С данные рассматриваются как поток байтов. Работа с потоком начинается с его открытия. Поток можно открыть для чтения и/или записи в двоичном или текстовом режиме.
Функция открытия потока имеет формат: FILE* fopen(const char* имя_файла, const char* режим);. При неудачном открытии потока функция возвращает NULL. Первый параметр – имя открываемого файла в виде С-строки, второй – режим открытия файла:
"r" – файл открывается для чтения;
"w" – открывается пустой файл для записи (если файл существует, он стирается);
"а" – файл открывается для добавления информации в его конец;
"r+" – открыть для чтения и записи (файл должен существовать);
"w+" – открыть пустой файл для чтения и записи (если файл существует, он стирается);
"a+" – файл открывается для чтения и добавления информации в его конец.
Режим открытия может также содержать символы t (текстовый режим) или b (двоичный режим). По умолчанию файл открывается в текстовом режиме. Приведём пример открытия бинарного файла для чтения:
FILE *f=fopen("c:\\data", "rb+");
Здесь, указатель f используется для дальнейших операций с потоком. Его передают функциям ввода/вывода в качестве параметра.
Ввод/вывод в поток можно осуществлять различными способами: в виде последовательности байтов, в виде символов и строк или с использованием форматных преобразований. Операции ввода/вывода выполняются начиная с текущей позиции потока, определяемой положением указателя потока. Текущее положение указателя можно получить с помощью функций ftell и fgetpos и задать явным образом с помощью функций fseek и fsetpos.
Чтение и запись потока байтов выполняют функции fread и fwrite; чтение символа из потока – getc, fgetc; запись символа в поток – putc, fputc; чтение строки из потока – fgets; запись строки в поток – fputs; форматированный ввод из потока – fscanf; форматированный вывод в поток – fprintf; закрытие потока явным образом – fclose.
Приведём пример программы на языке С, которая создаёт файл numbers.txt и записывает в него 5 введённых пользователем целых чисел.
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
using namespace std;
int main() {
const int K=5; //кол-во чисел
int n;
char fname[] = "c:\\os\\numbers.txt";
FILE *fout;
if((fout=fopen(fname, "wt"))==NULL) { //если при открытии текст. файла произ. ошибка
cout << "\nOshibka otkrytiya faila dlya zapisi!";
getch(); return 1;
}
for(int i=0; i<K; i++) {
cout << "Vvedite " << i+1 << "-e chislo: "; cin >> n;
fprintf(fout, "%i", n); //запись введённого числа в файл
fputc(' ', fout);
}
cout << "\n Chisla zapisany v fail!";
fclose(fout); //закрыть файловый поток
getch(); return 0;
}
А теперь рассмотрим программу, позволяющую считывать данные из созданного файла numbers.txt и вычислять среднее арифметическое значение считанных чисел.
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
using namespace std;
int main() {
int n, k=0, sum=0; //число, кол-во чисел, сумма чисел
float sr;
char fname[] = "c:\\os\\numbers.txt";
FILE *fin;
if((fin=fopen(fname, "rt"))==NULL) {
cout << "\nOshibka otkrytiya faila dlya zapisi!";
getch(); return 1;
}
cout << "Fail sodergit: ";
while(!feof(fin)) { //пока не конец файла
fscanf(fin, "%i", &n); //считать число
cout << " " << n;
sum = sum + n;
k++;
} //в файле после последней цифры не должно быть пробела
fclose(fin);
sr=(float)sum/n;
cout << "\nSumma chisel = " << sum;
cout << "\nSrednee arifm. = " << sr;
getch(); return 0;
}
В заключение хотел бы ещё раз отметить, что при работе с файлами лучше стараться применять потоковые классы С++, которые обеспечивают более надёжную работу как со стандартными, так и с определёнными пользователем типами данных, а также единообразный и понятный синтаксис.