6 Структурированные типы данных 2012
.pdf
|
|
|
11 |
pfm=new float[100]; |
// создание динамической переменной |
||
if (pfm==NULL) { |
cout << "No memory!!!"; // Проверка выделения памяти |
||
|
getch(); |
|
|
|
return -2; |
|
|
} |
// if |
|
|
cout << "\nFile name:" ; |
// запрос на ввод имени файла |
||
cin >> fname; |
|
// ввод |
имени файла с клавиатуры |
ofstream fout(fname, ios_base::out); |
// создание файлового потока |
||
if(!fout) { cout |
<< "\nFile error"; |
|
getch(); // приостановка закрытия окна консоли
|
return -10; |
// Возврат кода |
ошибки |
||
|
} // if |
|
|
|
|
cout << |
"\nN="; |
// |
Вывод на экран запроса |
||
cin >> N; |
// |
Ввод |
числа элементов |
массива |
|
for(int |
i=0;i<N;i++) |
// цикл |
обработки элементов массива |
{cout << "\nM[" << i << "]="; // Вывод запроса
cin >> *(pfm); |
|
// Ввод данных в массив через указатель |
fout << *(pfm) << " "; |
// Запись элемента вектора в файл |
|
pfm++; |
// изменение текущего адреса указателя на элемент |
|
} // конец цикла |
for |
|
fout.close(); |
// Закрытие файлового потока |
|
delete pfm; |
// уничтожение динамической переменной |
|
getch(); |
// приостановка |
закрытия окна консоли |
return 0; |
// Код успешного завершения программы |
} //---------------------------------------------------------------------------
6.8 Файловый тип данных и операции над файлами в C и C++
6.8.1 Общие сведения о потоках и файлах в языках C и C++
Вязыках программирования файловый тип данных используется для обмена данными между программой и файлами, хранящимися во внешней памяти, а также выполнять обмен данными с некоторыми устройствами компьютера. В С и С++ имеется расширенное толкование файлов через понятие потока. Поток - абстрактное понятие, относящееся к любому переносу данных от источника к приемнику (потребителю) данных. Потоки обычно связаны с файлами или некоторыми устройствами. Библиотека потоков iostream.h создает стандартный поток ввода cin, стандартный поток вывода cout и стандартный поток ошибок cerr. Программист может открывать дисковые файлы
исоздавать для них потоки. Также используются извлечение, прием и получение при вводе символов от источника, и вставка, помещение или запоминание при выводе символов на приемник. В языке С под файлом понимается любое абстрактное устройство, связанное с потоком ввода-вывода.
Файловые потоки связаны в программах с файловыми переменными, которые представляют их в программе.
Вязыке С и С++ различают два основных вида файлов:
1)файлы с произвольным доступом (например, дисковый файл), когда можно получить свободный доступ к любым его данным;
2)файлы с последовательным доступом (например, модем).
Над файлами и потоками в языке С используются следующие группы операций: 1) установочные для открытия файла, связывающие поток с конкретным файлом:
-открытия файла для чтения (допускает модификацию содержимого) файла;
-открытия файла для записи (очищает ранее созданный файл или создает новый);
-открытия для добавления данных в конец существующего файла;
2)закрытия файла, разрывающая связь файла и потока;
3)собственно ввод-вывод данных, который может выполняться:
-по элементно, считыванием отдельной скалярной переменной;
-через буфер – переменную структурированного типа;
4)перемещения и позиционирования внутри открытого файла;
5)внешние операции над файлом: копирование, удаление и т.п.
12
6.8.2 Открытие и закрытие файлов в языке С
В С файловый поток имеет тип FILE*, определенный в заголовочном файле stdio.h. Файловая переменная в С описывается как указатель на тип FILE. Формат описания:
FILE *имя_файловой_переменной;
Пример объявления: |
FILE *f; |
Файловая переменная |
– это указатель, использованный для открытия файла. |
После закрытия конкретного файла системы освобождается файловая переменная, которая теперь может быть использована для работы с другим файлом.
Перед тем как начать обмен данными между программой и файлом необходимо, открыть этот файл. Для открытия файла используется функция
Файловая_переменная=fopen(const char *имя_файла, const char *режим );
Функция возвращает указатель типа FILE, идентифицирующий файл. Если после открытия файла, он имеет значение NULL, то это означает ошибку открытия файла. При этом последующий контроль возникновения ошибки открытия удобно реализовать с помощью оператора if в формате
if (файл==NULL) { сообщение об ошибке; обработка ошибки }
Файл может быть открыт с использованием следующих режимов: для чтения, для записи данных (если эту операцию применить к уже существующему файлу, то его содержимое будет очищено) или для добавления данных в его конец.
Файл может быть открыт в двоичном и в текстовом режиме. В текстовом режиме файл состоит из строк символов, завершающихся нулевым \0.
Таблица 6.2 – Список модификаторов режима открытия файлов в языке С
Режим |
Значение |
|
|
“r” |
Открывает файл для чтения (по умолчанию – как текстовый) |
“w” |
Создает файл для записи (по умолчанию – как текстовый) |
“a” |
Открывает файл для добавления (по умолчанию – как текстовый) |
“rb” |
Открывает двоичный файл для чтения |
“wb” |
Открывает двоичный файл для записи |
“ab” |
Открывает двоичный файл для добавления. |
“r+” |
Открывает текстовый (по умолчанию) файл для чтения/записи |
“w+” |
Создает текстовый (по умолчанию) файл для чтения / записи |
“a+” |
Присоединяет текстовый (по умолчанию) файл для чтения / записи |
“r+b” |
Открывает бинарный файл для чтения/записи |
“w+b” |
Создает бинарный файл для чтения / записи |
“a+b” |
Присоединяет бинарный файл для чтения / записи |
|
|
“r+t” |
Открывает текстовый файл для чтения/записи |
“w+t” |
Создает текстовый файл для чтения / записи |
“a+t” |
Присоединяет текстовый файл для чтения / записи |
“rt” |
Открывает текстовый файл для чтения |
|
|
“wt” |
Создает текстовый файл для записи |
“at” |
Открывает текстовый файл для добавления |
Закрытие файла выполняется с помощью функции fclose в следующем формате: int fclose(FILE *файловая_переменная);
Пример открытия дискового текстового файла с именем data.txt для чтения /записи данных с контролем ошибки открытия:
FILE *f;
if ((f = fopen(“data.txt”,”r+t”)==NULL) { puts(“Ошибка открытия файла”); exit(1); }
Закрыть этот файл можно следующим образом: fclose(f);
Таблица 6.3 - Дополнительные функции для открытия файла из модуля stdio.h
Имя |
Описание |
Формат |
freopen |
Переоткрывает файловую переменную с новым |
FILE *freopen |
|
дисковым файлом |
(char новый_файл,ht bv) |
tmpfile |
Открывает временный файл (стираемый после |
FILE *tmpfile(void) |
|
закрытия) для обновления данных с |
|
|
уникальным именем |
|
13
6.8.3 Ввод и вывод в файл в языке программирования С
Ввод-вывод данных в файл выполняется с использованием модуля stdio. Таблица 6.4 – Функции ввода-вывода в файл модуля stdio.h
Имя |
Описание |
Формат |
|
|
|
putc() |
Записывает символ в файл |
putc(символ, файл) |
fputs() |
Записывает символ в файл |
Аналогично putc |
getc() |
Читает символ из файла |
символ = gets(файл) |
fgetc() |
Читает символ из файла |
Аналогично gets() |
fprintf() |
Форматированный вывод данных в файл |
fprintf(файл,формат,данные) |
fscanf() |
Форматированный ввод данных из файла |
fscanf(файл, формат, данные) |
remove() |
Стирает файл |
remove(файл) |
fread() |
Чтение блока данных из файла (ANSI С) |
fread(*буфер, размер, файл) |
fwrite() |
Запись блока данных в файл (ANSI C) |
Fread(*буфер, размер, файл) |
|
|
|
getw() |
Буферизированное чтение int из файла |
число = getw(файл) |
putw() |
Буферизированная запись чисел в файл |
puts (число, файл) |
fgets() |
Чтение строки из файла |
fgets(строка, длина, файл) |
|
|
|
fputs() |
Запись строки в файл |
fputs(строка, длинна, файл) |
Формат |
в fscanf и fprintf задается аналогично printf и scanf с помощью |
форматной строки. В форматной строке указываются следующие спецификаторы данных Таблица 6.5 – Спецификаторы формата данных для функций fprintf и fscanf
Спецификатор |
Описание |
%c |
Символ |
%d |
Знаковое десятичное целое число |
%I |
Знаковое десятичное целое число |
|
|
%e |
Действительное число в научной нотации (е – строчное) |
%E |
Действительное число в научной нотации (E – прописное) |
%f |
Десятичное действительное число с плавающей точкой |
%g |
Боле короткое представление %e и %f |
%G |
Боле короткое представление %E и %F |
|
|
%o |
Беззнаковое восьмеричное число |
%s |
Строка символов |
%u |
Беззнаковое целое десятичное число |
%x |
Беззнаковое шестнадцатеричное число строчными символами |
%X |
Беззнаковое шестнадцатеричное число прописными символами |
%p |
Вывод указателя |
%n |
Ассоционированный аргумент - указатель на целое число |
%% |
Вывод знака процентов % |
%[] |
Сканирует множество символов |
Многие |
спецификаторы формата используют модификаторы, уточняющие способ |
представления данных. Примеры:
%8d – минимальная ширина поля 8 символов с заполнением пустых позиций пробелами; %05i – минимальная ширина поля 5 с заполнением пустых позиций нулями
Модификатор точности указывается для вещественных чисел (%e, %f, %E) в формате %общая_длинна.символы_дробной_части, например %10.4f.
|
Модификатор вывода по левому краю при более короткой длине данных |
|||
выполняется с помощью указания символа |
-. Например %-20d |
|||
|
Модификаторы l и h используются для работы с длинными и короткими целыми |
|||
при модификаторах d, i, o, u и x. А |
так же l для e, f и g. |
|||
|
Спецификаторы * могут использоваться для задания минимальной ширины поля и |
|||
точности с помощью изменяемых данных |
|
|
||
|
“%*.*f”, длина_поля, длинна_дробной части, вещественное_число |
|||
|
Пример программы |
на языке |
С для формирования двоичного файла с |
|
возрастающей последовательностью из |
заданного числа целых чисел. |
|||
#include <stdio.h> |
|
/* |
Подключение модулей */ |
|
#include <conio.h> |
|
|
|
|
FILE *pfint; |
|
/* |
Файловая переменная */ |
|
char name[80]; |
|
/* |
Имя файла */ |
|
int |
size, |
|
/* |
Число элементов файла */ |
|
i=0; |
|
/* |
Переменная счетчик */ |
int main (void) |
/* главная функция программы */ |
|
|
|
|
14 |
|
|
{ puts("\n Введите имя файла\n"); |
/* Запрос имени файла на экране */ |
|||||
scanf("%s",name); |
|
/* Ввод имени файла с клавиатуры */ |
||||
printf("\n число элементов int |
= "); /* Запрос на число элементов */ |
|||||
scanf("%d",&size); |
|
/* Ввод числа элементов файла */ |
||||
pfint=fopen(name,"wb"); |
/* Открытие файла для записи */ |
|||||
for (i=1; i<=size; i++) fprintf(pfint,"%d",i); |
/* цикл записи */ |
|||||
fclose(pfint); |
|
|
|
/* закрытие файла */ |
||
return 0; |
|
/* код нормального завершения программы */ |
||||
}//----------------------------------------------------------------------- |
||||||
|
Пример программы расчета массивов точек функции с записью в текстовый файл |
|||||
#include <stdio.h> |
|
/* |
подключение модулей */ |
|||
#include <conio.h> |
|
|
|
|
|
|
const int size=30; |
|
/* |
размер массива */ |
|
||
float X[size], Y[size]; |
/* |
массивы аргумента и значения функции */ |
||||
float xn, xk, hx; |
|
/* |
начальное, конечное и шаг аргумента */ |
|||
int main(void) |
|
/* |
Главная функция программы */ |
|||
{ FILE *fp; |
|
/* |
Файловая переменная */ |
|||
int i=0; |
|
/* |
счетчик циклов */ |
|
||
char ans; |
|
/* |
Символ ответа на запрос */ |
|||
char name[80]; |
|
/* |
Имя файла на диске */ |
|
||
printf("\nXn="); |
|
/* |
Запрос на ввод начального значения X */ |
|||
scanf("%f",&xn); |
|
/* |
Чтение с клавиатуры xn */ |
|||
printf("\nXk="); |
|
/* |
Запрос на ввод конечного значения */ |
|||
scanf("%f",&xk); |
|
/* |
Чтение с клавиатуры xn */ |
|||
hx=(xk-xn)/(size-1); |
/* |
Расчет значения шага аргумента */ |
||||
X[0]=xn; |
|
/* |
Установка первого значения массива X */ |
|||
Y[0]=X[i]*X[i]; |
|
/* |
Расчет первого значения функции */ |
|||
for(i=1;i<size;i++) |
/* |
цикл расчета точек функции */ |
||||
{ X[i]=X[i-1]+hx; |
/* |
наращивание аргумента */ |
||||
|
Y[i]=X[i]*X[i]; |
/* |
расчет i-го значения массива функции */ |
|||
|
printf("\n %2d X= %8.5f Y= %8.5f",i,X[i],Y[i]); |
/* вывод точки */ |
||||
} |
|
|
/* |
конец тела цикла */ |
|
|
puts("\nСохранить результаты в |
файл?"); |
/* вывод запроса на экран */ |
||||
ans=getch(); |
|
|
|
/* чтение символа ответа */ |
||
if |
((ans=='Y')||(ans=='y')) |
|
/* проверка ответа */ |
|||
{ |
puts("\n‚Имя файла \n"); |
|
/* запрос имени файла */ |
|||
|
scanf("%s",name); |
|
|
/* чтение имени с клавиатуры */ |
||
|
fp=fopen(name,"wt"); |
|
/* открытие файла для чтения */ |
|||
|
for (i=0;i<size;i++) |
/* цикл записи i-ой точки в файл */ |
||||
|
fprintf(fp,"\n %2d X= %8.5f Y= %8.5f",i,X[i],Y[i]); /* запись в файл */ |
|||||
|
fclose(fp); |
|
|
|
|
/* закрытие файла */ |
} |
|
/* конец варианта записи результата в файл */ |
||||
return 0; |
/* возврат кода отсутствия ошибки */ |
|
||||
} |
|
/ * ---------------- конец программы -------------------- */ |
||||
|
Программа транспонирования |
матрицы, считываемой из файла из файла: |
||||
#include <stdio.h> |
|
/* подключение модулей */ |
|
|||
#include <conio.h> |
|
|
|
|
|
|
FILE |
*f1, |
|
/* исходный файл*/ |
|
|
|
|
*f2; |
|
/* файл результата */ |
|
|
|
char name1[80], |
|
/* Имя исходного файла */ |
|
|||
|
name2[80]; |
|
/* Имя файла результата */ |
|
||
float M1[3][3], |
|
/* Исходная матрица */ |
|
|
||
|
M2[3][3]; |
|
/* Матрица результата */ |
|
|
|
int main(void) |
|
|
|
|
|
|
{ do |
|
|
/* |
начало цикла ввода имени файла с коррекцией */ |
||
{ printf("\n Введите имя файла |
исходных данных \n"); |
|
||||
|
scanf("%s",name1); |
|
/* ввод имени файла f1 */ |
|||
|
f1=fopen(name1,"r+t"); |
/* открытие файла для чтения*/ |
||||
|
if (f1==NULL) |
printf("\n Ошибка открытия исходного файла!!!"); |
||||
} while(f1==NULL); |
|
/* конец цикла ввода */ |
||||
for(int i=0;i<3;i++) |
|
/* цикл индексов строк */ |
|
|
15 |
|
for(int j=0;j<3;j++) |
|
/* |
цикл индексов столбцов */ |
fscanf(f1,"%f",&M1[i][j]); |
/* |
чтение элемента из файла */ |
|
fclose(f1); |
|
/* |
закрытие файла f1*/ |
for(int i=0;i<3;i++) |
|
/* |
цикл индексов строк */ |
for(int j=0;j<3;j++) |
|
/* |
цикл индексов столбцов */ |
M2[i][j]=M1[j][i]; |
|
/* |
транспонирование элемента */ |
do |
/* начало цикла ввода имени файла с коррекцией */ |
||
{ printf("\n Введите имя файла результата \n"); |
|||
scanf("%s",name2); |
|
/* |
ввод имени файла f2 */ |
f2=fopen(name2,"w+t"); |
/* |
Открытие файла для записи*/ |
|
if (f2==NULL) printf("\n Ошибка открытия файла результата!!!"); |
|||
} while(f2==NULL); |
|
|
|
for(int i=0;i<3;i++) |
|
/* |
цикл вывода строк */ |
{ for(int j=0;j<3;j++) |
|
/* |
цикл вывода элемента строки */ |
fprintf(f2,"%8.3f |
",M2[i][j]); |
/* |
вывод элемента на экран */ |
fprintf(f2,"\n"); |
|
/* |
перевод строки */ |
} |
|
/* |
конец цикла вывода строк */ |
fclose(f2); |
|
/* |
закрытие файла f1 */ |
getch(); |
|
/* |
приостановка экрана */ |
return 0; |
|
/* |
код успешного завершения */ |
}//-------------------------------------------------------------------- |
|||
Для ввода-вывода переменных-массивов в |
файлы целиком следует использовать |
функции fread и fwrite соответственно. Их формат следующий:
fread(void *буфер, size_t размер_элемента, size_t число_элементов, FILE *файл); fwrite(void *буфер, size_t размер_элемента, size_t число_элементов, FILE *файл);
Функции возвращают число реально |
считанных (записанных) элементов. |
|||
Пример формирования двоичного |
файла с числами |
Фибоначчи используя fwrite |
||
#include <stdio.h> |
/* подключение модуля |
ввода-вывода */ |
||
unsigned long int F[100]; |
/* массив чисел Фибоначчи */ |
|||
int N=45; |
/* Количество чисел */ |
|
||
FILE *F1; |
/* Файл результатов */ |
|
||
char fname1[80]; |
/* Имя файла */ |
|
||
int main() |
|
|
|
|
{ F[0]=F[1]=1; |
|
/* |
Начальные значения числе */ |
|
for (int i=2; i<N; i++) |
|
/* |
Цикл расчета |
*/ |
{ F[i]=F[i-1]+F[i-2]; |
|
/* |
Расчет числа |
Фибоначчи */ |
printf("\n%2d %ld",i,F[i]); |
/* |
Вывод на экран числа */ |
||
} /* конец цикла for */ |
|
|
|
|
printf("Имя файла:"); |
|
/* |
Вывод запроса на ввод имени */ |
|
gets(fname1); |
|
/* |
Ввод имени с |
клавиатуры */ |
F1=fopen(fname1,"w+b"); |
|
/* |
Открытие файла */ |
|
fprintf(F1,"%d",N); |
|
/* |
Запись числа |
элементов */ |
fwrite(F,sizeof(long int),N,F1); |
/* |
Запись всего |
массива */ |
|
fclose(F1); |
|
/* |
Закрытие файла */ |
|
return 0; |
|
/* |
возврат кода |
успешного завершения */ |
}/* --------------- конец main -----------------------------*/
Пример программы чтения |
массива длинных целых чисел с использованием fread |
из бинарного файла, где первый элемент – размер массива. |
|
#include <stdio.h> |
|
unsigned long int F[100]; |
/* массив чисел Фибоначчи */ |
int N; |
/* Количество чисел */ |
FILE *F2; |
/* Файл результатов */ |
char fname2[80]; |
/* Имя файла */ |
int main() |
|
{printf("Имя файла:"); /* Вывод приглашения ввода имени файла */
gets(fname2); |
/* Ввод имени файла */ |
|
F2=fopen(fname2,"r+b"); |
/* открытие файла для чтения */ |
|
if(F2==NULL) { printf("\nОшибка открытия файла"); |
/* контроль ошибки*/ |
|
return 1; |
|
/* код ошибки */ |
} |
|
|
else { fscanf(F2,"%d",&N); |
/* Чтение первого |
элемента – размера */ |
|
16 |
|
|
|
fread(F,sizeof(long int),N,F2); |
/* Чтение массива |
*/ |
||
for(int i=0;i<N;i++) |
/* цикл вывода на |
экран */ |
||
printf("\n %2d |
%ld",i,F[i]); |
/* |
Вывод элемента |
массива */ |
fclose(F2); |
|
/* |
Закрытие файла |
*/ |
}
return 0; }//----------------------------------------------------------------------
Пример схемы алгоритма расчета параболы на заданном интервале с записью результатов в текстовый файл.
Начало
Запрос
Xn, Xk, Hx
X[0]=Xn
Начало цикла
Расчет Y[i]
X[i], Y[i]
X[i]=X[i-1]+Hx
Пока нет
конца файла
ans
Нет ans = Y
Да name
Открытие файла
i=1,…,N-1
X[i], Y[i]
Закрытие файла
Конец
Вывод сообщения о вводе исходных данных
Ввод значений переменных исходных данных с клавиатуры
Расчет значения шага изменения аргумента
Цикл расчета точек функции
Расчет по выражению текущего значения элемента массива Y
Вывод экран текущих значений переменных аргумента и функции
Расчет значения текущего элемента массива аргумента
Условие продолжения итераций
Ввод ответа на запрос о сохранении результатов
Проверка условия сохранения данных
Ввод по запросу в строковую переменную имени файла
Открытие нового текстового файла для записи данных
Запись строки в файл текущих значений переменных массивов
Рисунок 6.1 – Схема алгоритма расчета и записи функции в файл
17
Пример программы на языке С++ для расчета параболической функции на
заданном интервале с записью данных |
в текстовый файл. |
|
|||
#include <fstream.h> |
// подключение модуля файловых потоков |
||||
#include <iostream.h> |
// подключение модуля консольного ввода-вывода |
||||
char name[80]; |
// переменная имени файла |
||||
float Xn, Xk, Hx; |
// начало, конец и шаг |
изменения аргумента |
|||
float x[400], y[400]; |
// массивы функции |
|
|
||
int main() |
|
// |
головная программа |
||
{ cout << "\n Xn, Xk, Hx ? :"; |
|
// |
вывод запроса |
на экран |
|
cin >> Xn >> Xk >> Hx; |
|
// |
чтение данных |
с клавиатуры |
|
int i=0; |
|
// |
инициализация |
переменной -счетчика |
|
x[i]=Xn; |
|
// |
инициализация |
первого элемента |
|
do { y[i]=x[i]*x[i]; |
|
// |
цикл расчета функции |
||
cout << "\nX[" << i << "]=" << x[i] << " |
Y[" << i << "]=" << y[i]; |
||||
i++; |
|
// |
инкрементация |
счетчика |
|
x[i]=x[i-1]+Hx; |
|
// |
наращивание аргумента |
||
} while(x[i]<=Xk); |
|
// |
окончание цикла |
||
cout << "\nName:"; |
|
// |
приглашение для имени файла |
||
cin >> name; |
|
// |
чтение имени файла с клавиатуры |
||
ofstream fout(name,ios::out); |
// |
создание потока для вывода данных |
|||
for(int j=0;j<(i-1);j++) fout <<j<<" |
x="<<x[j]<<" |
y="<<y[j]<< endl; |
|||
fout.close(); |
|
// |
закрытие файлового потока |
||
return 0; |
|
// |
код успешного |
завершения программы |
}// конец программы ---------------------------------
6.8.4 Операции перемещения по файлу
При произвольном доступе к данным файла (для дисковых файлов), все операции ввода-вывода по умолчанию производятся последовательно. Имеет место так называемый маркер текущей позиции внутри файла. При открытии файла они устанавливается в начальное положение, затем при считывании данных производится автоматическое последовательное перемещение к последующим данным. При произвольном доступе имеется возможность перейти сразу на установленное число байт и выполнить операцию ввода или вывода только с этой позиции.
Таблица 6.6 - Функции для перемещения внутри элементов файла
Функция |
|
Описание |
|
Формат |
feof() |
|
Возвращает истину при достижении |
конца файла |
feof(файл) |
|
|
|
|
|
rewind() |
|
Установка индикатора перемещения |
на начало файла |
rewind() |
fseek() |
|
Переходит к указанному байту в файле |
fseek(fp,число,код) |
|
fseek() |
возвращает целочисленное значение |
и устанавливает |
текущую позицию в |
файле fp, смещенную на заданное число байт от начала отсчета, заданного кодом:
0– начало файла,
1– текущая позиция курсора;
2– конец файла.
Функция fseek() возвращает ноль в случае успешного перемещения и иное
значение |
при ошибке. |
|
|
|
Пример подпрограммы копирования |
данных из файла источника в файл копию |
|||
#include |
<stdio.h> |
/* подключение модулей */ |
|
|
#include |
<conio.h> |
|
|
|
long int |
size=0; |
/* размер файла в байтах |
*/ |
|
FILE *fsource; |
/* файл |
источник |
*/ |
|
FILE *fcopy; |
/* файл |
копия |
*/ |
|
char namesource[80]; |
/* имя |
файла источника */ |
|
|
char namecopy[80]; |
/* имя файла копии */ |
|
||
int main(void) |
/* главная функция программы */ |
{char data;
printf("\nИмя источника \n"); scanf("%s",namesource); fsource=fopen(namesource,"rb");
if (fsource==NULL) /* Проверка на наличие ошибки открытия */
18
{puts("\n Нет доступа к указанному файлу источнику ");
getch(); |
/* |
Приостановка закрытия экрана */ |
return -1; |
/* |
Вывод кода ошибки */ |
} /* if */ |
|
|
else |
|
|
{printf("\nИмя копии \n"); scanf("%s",namecopy);
fcopy=fopen(namecopy, "wb");
if (fcopy==NULL) /* Проверка на наличие ошибки открытия */
{ |
puts("\n Нет доступа к файлу копии "); |
} |
/* if */ |
else
{while (!feof(fsource)) /* цикл копирования до конца файла источника */ { data=getc(fsource); /* чтение символа из источника */
if (!feof(fsource)) putc(data,fcopy); /* |
запись данных в |
приемник |
*/ |
|
size++; |
/* |
счетчик размера |
файла */ |
|
}/* while */
printf("скопировано %ld |
байт",size); |
/* вывод |
отчета копирования */ |
||
fclose(fsource); |
/* |
закрытие |
файла источника |
*/ |
|
fclose(fcopy); |
/* |
закрытие |
файла копии */ |
|
}/* конец else */
}/* конец else */
getch(); |
/* экранная задержка */ |
|
return 0; |
/* |
код отсутствия ошибки выполнения */ |
} |
/* |
main */ |
|
Пример программы, выводящей на экран значение символа в заданной позиции, |
||
если |
ввести отрицательную позицию, тогда прекращается выполнение программы |
||
#include <stdio.h> |
/* |
подключение модулей */ |
|
#include <conio.h> |
|
|
|
FILE |
*f1; |
/* |
исходный файл*/ |
char |
name1[80]; |
/* |
Имя исходного файла */ |
char |
sim; |
/* |
Считываемый символ */ |
int Pos; |
/* |
Номер позиции в файле */ |
|
int main(void) |
|
|
|
{ do |
{ printf("\n Введите имя |
файла исходных данных \n"); |
|
|
scanf("%s",name1); |
|
|
|
f1=fopen(name1,"r+t"); |
|
|
|
if (f1==NULL) printf("\n |
Ошибка открытия исходного файла!!!"); |
|
|
} while(f1==NULL); |
|
|
do { printf("\n Введи позицию в файле = "); scanf("%d",&Pos);
fseek(f1,Pos,0);
getc(sim);
printf("\nСимвол - %c",sim); } while(Pos>=0);
fclose(f1);
getch(); return 0;
}//---------------------------------------------------------------
6.8.5 Прочие подпрограммы для работы с файлами
Таблица 6.7 - Функции модуля stdio.h для работы с дисковыми файлами
|
Имя |
|
Описание |
Формат |
|
|
|
|
|
|
remove |
Удаляет указанный файл |
int remove(const char *имя файл) |
|
|
rename |
Переименовывает файл |
int rename(char *старое, char*новое) |
|
|
tmpname |
Создает уникальное имя |
Char *tmpname(char *имя_файла) |
|
|
Пример программы переименования дискового файла: |
|||
#include <stdio.h> |
|
|
||
char fname1[80], |
/* старое имя файла */ |
|
||
|
fname2[80]; |
/* новое имя файла */ |
|
|
int main(void) |
|
|
{ printf("\n Старое имя файла \n"); /* Запрос на ввод старого имени файла */
|
|
19 |
|
|
gets(fname1); |
/* Чтение имени с |
клавиатуры |
*/ |
|
printf("\n Новое имя файла \n"); |
/* Запрос на ввод |
нового имени файла */ |
||
gets(fname2); |
/* |
Чтение имени с |
клавиатуры |
*/ |
if(rename(fname1,fname2)!=0) |
/* |
проверка наличия ошибки переименования */ |
{ printf("\n Ошибка переименования файлов"); /* сообщение об ошибке */
return 1; |
/* код ошибки */ |
} |
|
return 0; |
// код нормального завершения |
}//---------------------------------------------------------------------------- |
|
6.8.6 Работа с файлами в языке С++ |
|
ВС++ для работы с файлами используются специальные потоки. Ресурсы работы
сфайловыми потоками находятся в заголовочном файле fstream.h. В С++ файл
отрывается стыковкой его с потоком. В С++ используется три класса потоков: ввода, вывода и ввода-вывода. Открытие потоков - это определению объектов:
ifstream имя_потока; // файловый поток ввода данных из файла ofstream имя_потока; // файловый поток вывода
fstream имя_потока; // файловый поток ввода и вывода
После создания потока его связывают с файлом с помощью функции класса open(): void open(const char *name, int mode, int access=filebuf::openprot);
где mode определяет способ открытия файла:
ios::app – вводимые данные добавляются в конец файла; ios::ate – вызывает поиск конца файла в момент открытия файла ios::binary – открытие файла для бинарных операций.
ios::in – открытие файла для ввода;
ios::nocreate – когда открыт может быть только существующий файл; ios::noreplace – невозможно открыть файл если он уже создан ранее ios::out – открытие файла для вывода;
ios::trunk – уничтожение содержимого существующего файла до нуля
access – определяет доступ к файлу в DOS: 0-нормальный файл, 1 – только для чтения; 2 – скрытый; 4 – системный; 8 – архивный.
Можно производить связывание потока с именем файла сразу при его определении. При этом сразу после имени потока указывается список параметров.
Формат определения файлового потока для вывода данных в заданный файл ofstream имя_потока(имя_файла,ios::out);
Формат определения файлового потока для ввода данных из заданного файла ifstream имя_потока(имя_файла,ios::in);
Формат определения файлового потока для добавления данных в конец файла ofstream имя_потока(имя_файла,ios::app);
Закрытие файлового потока выполняется с помощью встроенной функции члена класса close(). При этом используется конструкция составного имени в формате
имя_потока.close();
Ввод и вывод данных из (в) файла производится соответственно с помощью операторов извлечения (>>) и передачи данных в поток (<<).
Формат чтения данных их файла аналогичен потоку cin: Файловый_поток >> имена_переменных ;
Формат вывод данных в файл аналогичен потоку cout: Файловый_поток << выводимые данные ;
Класс fstream используется для создания файлов, одновременно позволяющих и ввод, и вывод:
fstream inout("data”,ios::in\!ios::out);
inout << i; |
|
|
|
... |
|
|
|
inout >> j; |
|
|
|
Пример программы для |
расчета квадратной функции на заданном интервале. |
||
#include <fstream.h> |
|
|
// подключение модуля файловых потоков |
#include <iostream.h> |
|
|
// подключение модуля консольного ввода-вывода |
char name[80]; |
// |
переменная имени файла |
|
float Xn, Xk, Hx; |
// |
начало, конец и шаг изменения аргумента |
|
float x[400], y[400]; |
// |
массивы функции |
|
int main() |
|
|
// головная программа |
{ cout << "\n Xn, Xk, Hx ? |
:"; |
// вывод запроса на экран |
|
|
|
|
|
20 |
|
cin |
>> Xn >> Xk >> Hx; |
|
// чтение данных с клавиатуры |
|||
int |
i=0; |
|
|
// инициализация переменной -счетчика |
||
x[i]=Xn; |
|
|
// инициализация первого элемента |
|||
do { y[i]=x[i]*x[i]; |
|
|
// цикл расчета функции |
|||
|
cout << "\nX[" << i << "]=" << x[i] << " |
Y[" << i << "]=" << y[i]; |
||||
|
i++; |
|
|
// инкрементация счетчика |
||
|
x[i]=x[i-1]+Hx; |
|
|
// наращивание аргумента |
||
} while(x[i]<=Xk); |
|
|
// окончание цикла |
|||
cout << "\nName:"; |
|
|
// приглашение для имени файла |
|||
cin |
>> name; |
|
|
// чтение имени файла с клавиатуры |
||
ofstream fout(name,ios::out); |
// создание потока для вывода данных |
|||||
for(int j=0;j<(i-1);j++) fout <<j<<" |
x="<<x[j]<<" y="<<y[j]<< endl; |
|||||
fout.close(); |
|
|
// закрытие файлового потока |
|||
return 0; |
|
|
// код успешного завершения программы |
|||
} // --------------------- конец программы ------------------------------- |
||||||
|
Пример программы чтения таблично заданной функции парами точек из |
|||||
текстового файла с анализом данных таблицы. |
|
|||||
#include <iostream.h> |
|
|
|
|
|
|
#include <fstream.h> |
|
|
|
|
|
|
#include <conio.h> |
|
|
|
|
|
|
const |
int max=1000; |
// Максимальный размер массивов |
||||
char fname[80]; |
// Имя файла |
|
|
|
||
int N=0; |
|
// Число точек таблицы |
||||
double Xmax, Ymax=-1e90; |
// Максимальные значения |
|||||
double Xmin, Ymin=1e90; |
|
// Минимальные значения |
||||
double X[max], Y[max]; |
|
// Массивы исходных данных значений точек функции |
||||
double Ymiddle=0; |
|
// Среднее значение функции |
||||
double Ymiddle2=0; |
|
// Среднеквадратичное значение функции |
||||
double Xmiddle=0; |
|
// Среднее значение аргумента |
||||
double Xmiddle2=0; |
|
// Среднеквадратичное значение аргумента |
||||
double Xsum=0; |
|
// Суммарное значение аргумента |
||||
double Ysum=0; |
|
// Суммарное значение функции |
||||
ifstream fin; |
|
// файловый поток ввода |
||||
int main() |
|
// Главная функция программы --------------- |
||||
{ cout << "Введи имя файла:" << endl; |
// вывод сообщения |
|||||
cin |
>> fname; |
|
|
|
// ввод имени файла |
|
fin.open(fname,ios::in); |
|
|
// открытие потока для чтения |
|||
if (!fin) { cout << "Не открыт файл!"; // проверка ошибки открытия файла |
||||||
|
getch(); |
|
|
|
// Приостановка закрытия консоли |
|
|
return -1; |
|
|
// Код ошибки |
||
|
} |
|
|
|
|
|
while(!fin.eof()) |
// |
цикл чтения пока нет конца файла |
||||
{ |
fin >> X[N] >> Y[N]; |
// чтение точки таблицы из файла |
||||
|
cout << X[N] << " " << Y[N] << endl; // вывод точки на экран |
|||||
|
Xsum+=X[N]; |
|
// наращивание суммы X |
|||
|
Ysum+=Y[N]; |
|
// наращивание суммы Y |
|||
|
Ymiddle+=Y[N]; |
|
// наращивание суммы среднего Y |
|||
|
Ymiddle2+=Y[N]*Y[N]; |
// наращивание среднеквадратичного Y |
||||
|
Xmiddle+=X[N]; |
|
// наращивание суммы среднего Y |
|||
|
Xmiddle2+=X[N]*X[N]; |
// наращивание среднеквадратичного Y |
||||
|
if (Y[N]>Ymax) { Ymax=Y[N]; |
// Определение максимума |
||||
|
|
Xmax=X[N]; |
|
|
|
|
|
} |
|
|
|
|
|
|
if (Y[N]<Ymin) { Ymin=Y[N]; |
// Определение минимума |
||||
|
|
Xmin=X[N]; |
|
|
|
|
|
|
|
} |
|
|
|
|
N++; |
// Инкрементация счетчика точек |
||||
|
} // конец тела цикла while |
|
|
|
||
|
N--; |
|
// Коррекция счетчика |
|||
|
fin.close(); |
|
// Закрытие файла |
|
||
|
Ymiddle=Ymiddle/N; |
// Расчет среднего значения Y |