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

техпрог / Comp-Sci-12a

.pdf
Скачиваний:
45
Добавлен:
10.02.2015
Размер:
952.97 Кб
Скачать

Материалы к лекции 12

Объектно-ориентированное программирование

Файловый ввод-вывод в C и C++

Схема работы с файлами на языке C

Файлы представляют собой области памяти на внешнем носителе и могут использоваться для долговременного хранения информации. Файлы имеют имена и организованы в иерархическую древовидную структуру. В системах MS DOS и UNIX файлы не имеют предопределенной структуры и являются просто линейными массивами байт. Доступ к элементам файла осуществляется последовательно и происходит в так называемой ―позиции чтения-записи‖, которая автоматически продвигается при операциях чтениязаписи.

Системные вызовы работаю с файлами как с неструктурированным массивом байт, что не всегда удобно при программировании задач, ориентированных на обработку текста.

В языке C имеется специальная библиотека функций stdio – стандартная библиотека ввода-вывода (standard input/output library).

Схема работы с файлами с помощью этой библиотеки следующая.

1.Каждый открытый файл должен иметь указатель типа FILE, используемый для ссылок на файл. Функции C работают не с именами файлов, а с указателями на файл.

2.С помощью функции fopen() указатель на файл связывается с физическим файлом на диске и указывается режим открытия файла.

3.После выполнения операция с файлом, необходимо вызвать функцию закрытия файла fclose().

Как записать информацию в текстовый файл – простой пример

Пример. Запись в файл (как принято в C).

// file1.cpp : Пример записи в текстовый файл

//

#include "stdafx.h" #include <stdio.h> #include <iostream> using namespace std;

FILE *f, *fopen();

int _tmain(int argc, _TCHAR* argv[])

{

int i,x;

f=fopen("c:\\tmp\\result.txt","w");

for(i=0;i<100;i++)

{

x=i*2;

fprintf(f," %d ",x);

}

fclose(f);

return 0;

}

Пример. Запись в файл с проверкой дисковой операции (как принято в C). Если fopen() не может открыть файл, возвращается значение NULL

// file2.cpp : Пример записи в файл

//

#include "stdafx.h" #include <stdio.h> #include <iostream> using namespace std; FILE *f, *fopen();

int _tmain(int argc, _TCHAR* argv[])

{

int i,x;

if((f=fopen("inf.txt","w"))==NULL)

{

printf("File-Error!!!"); return 1;

}

for(i=0;i<100;i++)

{

x=i*2;

fprintf(f," %d ",x);

}

fclose(f); return 0;

}

Как прочитать информацию из текстового файла – простые примеры

Пример. Чтение данных из файла

// file3.cpp : Чтение из файла

//

#include "stdafx.h" #include <stdio.h> #include <iostream> using namespace std;

FILE *f, *fopen();

int _tmain(int argc, _TCHAR* argv[])

{

int i,t; int x[10];

if((f=fopen("c:\\tmp\\dannye.txt","r"))==NULL)

{

printf("File-Error!!!"); return 1;

}

for(i=0;i<10;i++)

{

fscanf(f,"%d",&t);

x[i]=t;

cout<<"\n x="<<x[i];

}

fclose(f);

return 0;

}

Пример. Чтение всей информации из файла. С помощью функции feof() можно определить установлен ли индикатор конца файла

// file4.cpp : Чтение из файла

//

#include "stdafx.h" #include <stdio.h> #include <iostream> using namespace std; FILE *f, *fopen();

int _tmain(int argc, _TCHAR* argv[])

{

int i,t; int x[10];

if((f=fopen("c:\\tmp\\dannye.txt","r"))==NULL)

{

printf("File-Error!!!"); return 1;

}

i = 0;

while (!feof(f))

{

fscanf(f,"%d",&t);

x[i]=t;

cout<<"\n x="<<x[i++];

}

fclose(f); return 0;

}

ВОПРОС. Если в файле более 10 чисел (например, 100), смогут ли они сохраниться в массиве x?

Отметим, что в системе UNIX признак конца файла в самом файле не хранится. Система определяет длину файла в байтах, признак конца файла (EOF) вырабатывается стандартными функциями тогда, когда обнаруживается, что указатель чтения достиг конца файла, т.е. позиция чтения стала равной длине файла.

В системе MS DOS признак конца файла (EOF) хранится в текстовых файлах явно и обозначается CTRL/Z.

Проверка на конец файла при посимвольном чтении может быть такой

int ch;

while ((ch=getchar(f)) != EOF)

{

}

Операции с файлами – примеры

Пример. Чтение из файла и выделение слов.

#include <stdio.h> #include <ctype.h> #include <string.h> #include <iostream> using namespace std; FILE *f, *fopen(); int get_word(char *); int main()

{char word[80];/* слово, выделенное из файла */

int kol=0; /* количество слов в в файле */ if((f=fopen("readme.txt","r"))==NULL){printf("File-

Error!!!"); return 1;} while (get_word(word))

{/* цикл продолжается пока get_word() не равно 0*/ kol++; cout<<word<<' ';

}

fclose(f); return 0;

}

int get_word(char *a)

{/* возвращает 1, если из файла прочитано слово*/ /* слово передается через параметр a*/

char ch, i=1;

while (!isalpha(ch=getc(f))&&ch!=EOF); if(ch==EOF) return 0;/* файл кончился*/ a[0]=ch;

while(isalpha(ch=getc(f))&&ch!=EOF) a[i++]=ch; a[i]='\0';

return 1;

}

Пояснения. По поводу символьных функций см., например, С. Прата, стр. 255. Функция isalpha() возвращает true, если аргумент является символом алфавита.

Стандартные задачи на файлы

1.Дан текстовый файл f, получить копию файла f в файле g.

2.Даны текстовые файлы f и g. Записать в файл h сначала компоненты файла f, а затем

— компоненты файла g.

3.Даны текстовые файлы f и g. Написать программу, которая печатает информацию вперемежку из двух файлов: одна строка из файла f, другая – из файла g и т.д.

4.Написать программу сравнения двух текстовых файлов – на печать должна выводится первая из различающихся строк, а также номер этой строки и позицию символа, в котором они различаются.

5. Дан текстовый файл f. Создать файл g, образованный из файла f заменой всех прописных букв одноименными строчными.

6.Дан текстовый файл f. Подсчитать количество строк и символов в файле f. Указание (из А.Богатырев. Язык Си в системе UNIX, стр. 130): надо подсчитать количество символов ‘\n’ в файле и учесть, что последняя строка файла может не иметь этого символа на конце. Поэтому, если последний символ файла не есть ‘\n’, то нужно добавить к счетчику строк 1.

7.Дан текстовый файл f. Подсчитать количество вхождений каждого из символов алфавита в файле f.

8. Дан текстовый файл f. Подсчитать количество слов в файле f.

9. Дан текстовый файл f. Подсчитать в файле f количество слов заданной длины n.

10. Подсчитать количество вхождений данного слова s в текстовый файл.

11. Дан текстовый файл f, содержащий информацию в кодировке DOS (OEM – 866). Преобразовать информацию в кодировку Windows (Win-1251).

12. Дан текстовый файл f, содержащий информацию на русском языке. Преобразовать текст, заменив символы кириллицы на ―подходящие‖ латинские буквы (для букв, не имеющих аналогов в латинице, использовать сочетания букв, например, ―ж‖ — ―zh‖, ―х

— ―kh‖, ―ц‖ — ―ts‖, ―ч‖ — ―ch‖, ―ш‖ — ―sh‖, ―щ‖ — ―tsh‖, ―ю‖ — ―ju‖, ―я‖ — ―ja‖).

Преобразованный текст записать в файл g.

13. Дан текстовый файл f. Найти слово (слова), встречающиеся наиболее часто.

14. Дан текстовый файл f. Вычислить количество вхождений каждого символа в файле f. Результат сохранить в массиве.

Система ввода – вывода языка C++

Язык C++, как уже было показано, поддерживает операции с файлами с использованием функций, объявленных в stdio.h. Таким образом, можно использовать тот же код, что и в программах на языке C. Заметим, что вместо директивы, принятой в программе на C,

#include <stdio.h>

в программах на языке C++ записывают

#include <cstdio> using namespace std;

Рекомендуется в программах на C++ использовать ввод-вывод с использованием набора классов, определенных в заголовочных файлах iostream (iostream.h) и fstream (fstream.h).

С точки зрения программы, написанной на C++, ввод-вывод представляется как поток байтов. При вводе программа читает байты из потока ввода, а при выводе вставляет байты в поток вывода. Байты потока поступают с клавиатуры, из другой программы, с устройства хранения данных (например, диск). Управление вводом предполагает две стадии:

Присоединение потока ввода к программе

Связывание потока с файлом.

Пример. Создаѐм файл (“test.txt”) для записи, записываем в него информацию и закрываем. Снова открываем этот же файл, но уже для чтения, выводим часть информации из файла на экран.

#include <iostream> #include <fstream> using namespace std; int main()

{ofstream fout("test.txt"); // создание файла для вывода

if(!fout) { cout << "Файл открыть невозможно\n"; return 1; } fout << "Hello!\n";

fout << 100 <<' '<<200<< endl;

fout.close(); // Чтение из файла:

ifstream fin("test.txt"); // открытие файла для ввода

if(!fin) { cout << "Файл открыть невозможно\n"; return 1; } char str[80];

int i;

fin >> str >> i;

cout << str << ' ' << i << endl;

fin.close();

return 0;

}

Пример. Создаѐм файл (primer.txt) и записываем в него информацию, введенную с клавиатуры.

#include <iostream> #include <fstream> using namespace std; int main()

{

ofstream my_out("primer.txt"); // файл для вывода

if(!my_out) { cout << "Файл открыть невозможно\n"; return 1; } char str[80];

cout << "Vvodim stroku, okonchim - !\n"; do

{cout << "Stroka= "<<endl; cin >> str;

my_out << str << endl;

} while (*str != '!');

my_out.close();

return 0;

}

Пример. Читаем из одного файла, преобразуем информацию и записываем в другой файл.

#include <iostream> #include <fstream> using namespace std; int main()

{ifstream fin("file1.txt"); /* этот файл уже создан (из

него вводим) */

ofstream fout("file2.txt"); /* этот файл будет создан (в

него записываем) */

if(!fout) { cout << "Файл открыть невозможно\n"; return 1; } if(!fin) { cout << "Файл открыть невозможно\n"; return 1; } char ch;

fin.unsetf(ios::skipws); // не пропускать пробелы

while(!fin.eof()) {

fin >> ch; if(ch==',') ch = '|';

if(!fin.eof()) fout << ch;

}

fin.close();

fout.close();

return 0;

}

Пример. Подсчет числа слов в текстовом файле

#include <iostream> #include <fstream> #include <cctype> using namespace std; int main()

{

ifstream in("file1.txt");

if(!in) {

cout

<< "File--Error!!!!!\n"; return 1; }

int count

= 0;

char ch;

in >> ch; // нахождение первого символа не пробела in.unsetf(ios::skipws); // не пропускать пробелы while(!in.eof()) {

in >> ch;

if(isspace(ch)|| in.eof()) { count++; while(isspace(ch) && !in.eof()) in >> ch;

}

}

cout << "Vsego slov: " << count << '\n'; in.close();

return 0;

}

Соседние файлы в папке техпрог