Работа с файлами с использованием конструкций языка Си была рассмотрена здесь.
Для программиста открытый файл представляется как последовательность считываемых или записываемых данных. При открытии файла с ним связывается поток ввода-вывода. Выводимая информация записывается в поток, вводимая информация считывается из потока.
Для работы с файлами необходимо подключить заголовочный файл <fstream>. В нем определены несколько классов и подключены заголовочные файлы
- <ifstream> — файловый ввод ;
- <ofstream> — файловый вывод.
Файловый ввод-вывод аналогичен стандартному вводу-выводу, единственное отличие – это то, что ввод-вывод выполнятся не на экран, а в файл.
Если ввод-вывод на стандартные устройства выполняется с помощью объектов cin и cout, то для организации файлового ввода-вывода достаточно создать собственные объекты, которые можно использовать аналогично этим операторам.
При работе с файлом можно выделить следующие этапы:
- создать объект класса fstream (возможно, ofstream или ifstream);
- связать объект класса fstream с файлом, который будет использоваться для операций ввода-вывода;
- осуществить операции ввода-вывода в файл;
- закрыть файл.
2
3
4
5
6
7
8
9
10
using namespace std;
int main()
{
ofstream fout;
fout.open("file.txt");
fout << "Привет, мир!";
fout.close();
return 0;
}
В результате будет создан файл
Режимы открытия файлов устанавливают характер использования файлов. Для установки режима в классе ios предусмотрены константы, которые определяют режим открытия файлов.
Константа | Описание |
ios::in | открыть файл для чтения |
ios::out | открыть файл для записи |
ios::ate | при открытии переместить указатель в конец файла |
ios::app | открыть файл для записи в конец файла |
ios::trunc | удалить содержимое файла, если он существует |
ios::binary | открытие файла в двоичном режиме |
Режимы открытия файлов можно устанавливать непосредственно при создании объекта или при вызове метода open().
fout.open("file.txt", ios::app);
Режимы открытия файлов можно комбинировать с помощью поразрядной логической операции ИЛИ |, например:
ios::out | ios::in - открытие файла для записи и чтения.
Произвольный доступ к файлу
Система ввода-вывода С++ позволяет осуществлять произвольный доступ с использованием методов seekg() и seekp().
- ifstream &seekg(Смещение, Позиция);
- ofstream &seekp(Смещение, Позиция);
Смещение определяет область значений в пределах файла (long int).
Система ввода-вывода С++ обрабатывает два указателя, ассоциированные с каждым файлом:
- get pointer g - определяет, где именно в файле будет производиться следующая операция ввода;
- put pointer p - определяет, где именно в файле будет производиться следующая операция вывода.
Позиция смещения определяется как
Позиция | Значение |
ios::beg | Начало файла |
ios::cur | Текущее положение |
ios::end | Конец файла |
Всякий раз, когда осуществляются операции ввода или вывода, соответствующий указатель автоматически перемещается.
С помощью методов seekg() и seekp() можно получить доступ к файлу в произвольном месте.
Можно определить текущую позицию файлового указателя, используя следующие функции:
- streampos tellg() - позиция для ввода
- streampos tellp() - позиция для вывода
Пример на С++
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <fstream>
using namespace std;
int main()
{
system("chcp 1251");
system("cls");
char s[80];
fstream inOut;
inOut.open("file.txt", ios::out);
inOut << "строчка текста" << endl;
inOut.seekp(8, ios::beg);
inOut << "еще строчка текста";
inOut.close();
inOut.open("file.txt", ios::in);
inOut.seekg(-6, ios::end);
inOut >> s;
inOut.close();
cout << s;
cin.get();
return 0;
}
В результате выполнения первой части программы будет создан файл
Вторая часть программы выведет в консоль
Ещё один пример. Допустим, нам нужно заполнять таблицу
ФИО | Дата рождения | Хобби |
Причем каждая вновь введенная строка должна размещаться в таблице непосредственно под "шапкой".
Алгоритм решения задачи следующий:
- формируем очередную строку для вывода
- открываем файл для чтения, считываем из него данные и сохраняем их в массив строк
- закрываем файл
- открываем файл для записи
- выводим "шапку" таблицы
- выводим новую строку
- выводим все сохраненные строки обратно в файл, начиная со строки после шапки
Пример на C++
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <fstream>
using namespace std;
#define LINES 100 // максимальное количество строк в файле
int main() {
system("chcp 1251");
system("cls");
char line[LINES][100];
char str[30];
char s[] = "| | | |";
// Ввод данных для размещаемой строки
cout << "ФИО: ";
cin.getline(str, 30); // вводим ФИО
for (int i = 0; str[i] != '\0'; i++) // копируем в строку без 0
s[i + 2] = str[i]; // начиная с указанной позиции
cout << "Дата: ";
cin.getline(str,30);
for (int i = 0; str[i] != '\0'; i++)
s[i + 33] = str[i];
cout << "Хобби: ";
cin.getline(str,30);
for (int i = 0; str[i] != '\0'; i++)
s[i + 50] = str[i];
fstream inOut;
inOut.open("file.txt", ios::in); // открываем файл для ввода
// Считываем из файла имеющиеся данные
int count = 0;
while (inOut.getline(line[count], 100)) count++;
inOut.close(); // закрываем файл
inOut.open("file.txt", ios::out); // открываем файл для вывода
inOut << "--------------------------------------------------------------------------------" << endl;
inOut << "| ФИО | Дата | Хобби |" << endl;
inOut << "--------------------------------------------------------------------------------" << endl;
inOut << s << endl; // выводим сформированную строку
inOut << "--------------------------------------------------------------------------------" << endl;
// Выводим обратно в файл все строки кроме "шапки" (первые 3 строки)
for (int j = 3; j < count; j++)
{
inOut << line[j] << endl;
}
inOut.close();
cin.get();
return 0;
}
Результат выполнения:



Полученный файл данных:
Назад: Программирование микроконтроллеров
Если данные из файла считываются, то они не удаляются. Удаление данных происходит только при открытии файла в режиме записи (строка 32 последнего примера в статье).
2
3
for(i=0; i<4; i++) inOut.getline(line[i], 100);
inOut.getline(line[i], 100); // вот Ваша 4-ая строка
for(int i=0; i<100; i++) cout<<line[4][100]; Тоже не работает
2
cout << line[3];
2
3
4
5
cout >> "filename: ";
cin << filename;
inOut.open(filename, ios::in);
...
2
3
4
5
6
7
textoutbuf.push_back('\n');
//m_sock.fileLog << "yjjfhjshdsjhf dkcfjdhj jfcjh 111111";
m_sock.fileLog << textoutbuf;
INT qqq = GetLastError();
m_sock.fileLog.flush();//очистить поток
m_sock.fileLog.close();
2
3
4
5
6
7
8
9
10
11
12
13
using namespace std;
int main()
{
ofstream m_sock;
m_sock.open("C://1/file.txt");
char textoutbuf[] = "yjjfhjshdsjhf dkcfjdhj jfcjh 111111\n";
m_sock << textoutbuf;
m_sock << "yjjfhjshdsjhf dkcfjdhj jfcjh 111111";
m_sock.flush();
m_sock.close();
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using namespace std;
int main()
{
string buf;
ifstream infile;
infile.open("text.txt", ios::in);
if(infile.is_open()){
infile >> buf;
short n = strlen(buf);
short k=0;
if(n%2) {
k = n/2;
cout << buf[k];
}
else cout << buf[k] << " " << buf[k+1];
}
else{
cout << "File error."<< endl;
return 1;
}
infile.close();
return 0;
}