Як прочитати один рядок з файлу з




Як прочитати один рядок з файлу з



C++. Приклади роботи із текстовими файлами. Модифікація файлів. Сортування даних у файлах. Конвертування даних файлу до списку

Приклади роботи із текстовими файлами. Модифікація файлів. Сортування даних у файлах. Конвертування даних файлу в масив

У цій темі наводяться приклади вирішення відомих завдань, що виникають під час обробки текстових файлів мовою C++. Пропрацювавши рішення цих завдань, ви навчитеся обробляти масиви малих даних, керувати розподілом пам'яті і використовувати засоби C++ для роботи з текстовими файлами.

Пошук на інших ресурсах:

1. Як визначити, що дані у текстовому файлі закінчились?

Для визначення кінця файлу використовується функція eof(). Функція повертає результат типу bool. Прототип функції наступний

тут std – простір імен, у якому оголошено функцію eof() .

Якщо під час виклику функції поточний покажчик читання вказує на кінець файлу, функція повертає true . В іншому випадку функція повертає false.

приклад 1.

Нижче наведено фрагмент коду, в якому використовується функція eof() для визначення, чи досягнуто кінець файлу, якому відповідає екземпляр з ім'ям inputFile

if (inputFile.eof() ==  false) < cout "End of file not reached."; >
else < cout "End of file is reached."; >

приклад 2.

Найчастіше функція eof() використовується в циклі while під час читання рядків файлу

while (!inputFile.eof())  // поки не кінець файлу
< // Зчитування рядків із файлу
// . >

Як тільки буде досягнуто кінець файлу inputFile , відбудеться вихід з циклу.

2. Функція CountLinesInFile(). Підрахунок кількості рядків у текстовому файлі

Функція CountLinesInFile() повертає кількість рядків у текстовому файлі.

Використання функції GetStringsFromFileC() може бути, наприклад, таким:

void main() <  // Виведення списку рядків файлу на екран
// 1. Оголосити внутрішні змінні
int count;  // кількість рядків
char** lines =  nullptr; // Список рядків типу char*
//2.Отримати список рядків типу char** count = GetStringsFromFileC("TextFile1.txt", &lines);  // 3. Перевірка, чи отримано список
if (count < 0) < cout "Error" return; >
// 3. Вивести список рядків на екран
for (int i = 0; i < count; i++) < cout  // 4. Звільнити пам'ять, виділену кожному за рядка lines
if (Lines! =nullptr) for (int i = 0; i < count; i++)  delete lines[i];  // 5. Звільнити пам'ять, виділену для масиву lines
if (Lines! =  nullptr) delete[] lines; >
4. Функція GetStringsFromFileS(). Отримати масив рядків типу string із текстового файлу

Робота з типом string зручніша ніж з типом char*. У наступному фрагменті коду реалізовано функцію GetStringsFromFileS() , що читає рядки з текстового файлу і записує їх у масив (список) типу string . Ця функція використовує функцію CountLinesInFile() , яка описується в пункт 2 цієї теми.

#include
using namespace std;  // модуль необхідний роботи з файлами
#include
// Функція, яка отримує рядки файлу як списку типу string*
// Параметри:
// - filename - ім'я файлу;
// - _lines - Список рядків файлу типу (string *).
// Функція повертає загальну кількість прочитаних рядків.
int GetStringsFromFileS(string filename,  string** _lines) <  // 1. Додаткові змінні
string* lines;  // Тимчасовий список рядків
int n = CountLinesInFile(filename);  // Отримати кількість рядків у файлі
// 2. Перевірка, чи правильно прочитані рядки з файлу
if (n == -1)  return -1; // 3. Оголосити файлову змінну та відкрити файл filename для читання ifstream F(filename);  // 4. Перевірка, чи файл відкритий
if (!F)  return -1; // 5. Спроба виділити пам'ять для n рядків типу string
try < lines =  new
string[n]; >  catch (bad_alloc e) < cout // вивести повідомлення про помилку F.close();  return -2; // Повернення з кодом -2 >
// 6. Читання рядків із файлу та запис рядків до списку lines
char buffer[1000];  // буфер для читання рядка
for (int i = 0; i < n; i++) <  // 6.1. Прочитати рядок з файлу до буфера buffer F. getline (buffer, 1000);  // 6.2. Обчислити довжину прочитаного рядка
int len;  for (len = 0; buffer [len]! =  '\0'; len++);  // 6.3. Записати buffer => lines[i], використовувати метод assign().
// Скопіювати len байт із buffer в lines[i]. lines[i].assign(buffer, len); >  // 7. Закрити файл F.close();  // 8. Повернути результат *_lines = lines;  return n; >

Використання функції GetStringsFromFileS() може бути, наприклад, наступним

void main() <  // Виведення списку рядків файлу на екран
// 1. Оголосити внутрішні змінні
int count;  // кількість рядків
string* lines =  nullptr; // Список рядків типу string
// 2. Отримати список рядків типу string* count = GetStringsFromFileS("TextFile1.txt", &lines);  // 3. Перевірка, чи отримано список
if (count < 0) < cout "Error" return; >
// 3. Вивести список рядків на екран
for (int i = 0; i < count; i++) < cout  // 4. Звільнити пам'ять, виділену для масиву lines
if (Lines! =  nullptr) delete[] lines; >

Результат роботи програми (вміст файлу TextFile1.txt):

#include using namespace std; void main()
5. Функція SetStringsToFileS(). Записати масив (список) рядків типу string у текстовий файл

Працюючи з текстовими файлами корисна функція SaveStringsToFileS() , яка записує масив рядків у файл. У наведених нижче прикладах ця функція буде використовуватися для запису модифікованого списку у файл.

#include
using namespace std;  // модуль необхідний для роботи з
файлами #include

//
Функція, яка записує масив рядків типу string у текстовий файл. // Параметри: // – filename – ім'я файлу; // - lines - масив рядків, які записуються у файл; // - count – кількість рядків. // Функція повертає true, якщо запис рядків відбувся успішно.
bool SetStringsToFileS(string filename,  string* lines,  int count) <  // 1. Оголосити додаткові змінні ofstream F(filename);  // відкрити файл для запису
// 2. Перевірка, чи успішно відкрився файл
if (!F)  return false; // 3. Запис рядків у файл крім останнього рядка
for (int i = 0; i < count – 1; i++) F // 4. Останній рядок записати як є (без символу '\n') F // 5. Закрити файл F.close();  // 6. Повернути результат
return true; >

Нижче наведено приклад використання функції SetStringsToFileS().

void main() <  // Запис масиву рядків у файл
// 1. Оголосити внутрішні змінні
int count;  // кількість рядків
string* lines =  nullptr; // Список рядків типу string
// 2. Сформувати рядки
try
< // Спроба виділити пам'ять для 5 рядків lines =  new
string[5]; >
catch (bad_alloc e) < cout return; >
// записати в рядки певний текст lines[0] =  "#include "; lines[1] =  "using namespace std"; lines[2] =  "void main()"; lines[3] =  "; lines[4] =  ">"; // 3. Записати рядки у файл TextFile2.txt
if (SetStringsToFileS("TextFile2.txt", lines, 5)) cout "OK!" else cout "Error." // 4. Звільнити пам'ять, виділену для масиву lines if (Lines! =  nullptr) delete[] lines; >
6. Функція ChangeStringInFileC(). Заміна рядка у текстовому файлі

У прикладі наведено функцію, яка замінює рядок у файлі в заданій позиції. Ця функція використовує такі функції:

  • CountLinesInFile() - визначає кількість рядків у файлі (реалізована в п. 3);
  • GetStringsFromFileC() - повертає рядки файлу у вигляді масиву (реалізована в п. 4). Рядки представлені типом char*.

Ця функція не використовує додатковий файл для копіювання. Функція отримує рядки файлу у вигляді списку lines, які є копією файлу. Потім відбувається запис цих рядків у цей файл за винятком рядка, яку потрібно замінити у файлі. У позиції заміни записується вхідний рядок заміни. Таким чином відбувається заміна рядка у текстовому файлі.

#include
using namespace std;  // модуль необхідний роботи з файлами
#include
// Функція, що замінює рядок у файлі.
// Параметри:
// - filename - ім'я файлу;
// - position - позиція рядка у файлі, який потрібно замінити;
// - str - рядок, що замінює рядок у файлі.
// Функція повертає true, якщо операція заміни рядка пройшла успішно.
bool ChangeStringInFileC(string filename,  int position,  string str) <  // 1. Отримати рядки файлу як списку
char** lines;  // Список рядків файлу
int count;  // кількість рядків файлу count = GetStringsFromFileC(filename, &lines);  // отримати список lines
// 2. Перевірка, чи коректно прочитаний файл
if (count < 0)  return false; // 3. Перевірка, чи правильна позиція 0  if ((position < 0) | | (position > = count))  return false; // 4. Запис рядків lines у файл до позиції position ofstream F(filename);  // відкрити файл для запису
// 5. Перевірка, чи відкрився файл коректно – функція is_open()
if (!F.is_open())  return false; for (int i = 0; i <position; i++) F // вивести рядок у файл
// 6. Запис рядка з позиції position F // тут пишеться рядок str
// 7. Запис рядків після позиції position
for (int i = position + 1; i < count – 1; i++) F // 8. Записати останній рядок без символу '\n' F // 9. Закрити файл F.close();  // 10. Звільнити пам'ять, виділену для рядків
for (int i = 0; i < count; i++)  delete lines[i];  // 11. Звільнити покажчики на рядки
delete[] lines; >

Використання цієї функції може бути, наприклад, таким:

void main() <  // Заміна вхідного рядка у файлі
string filename = "TextFile1.txt";  // вихідний файл
int pos = 5;  // Вихідна позиція рядка
string str =  "Hello world!"; // Вихідний рядок заміни
if (ChangeStringInFileC(filename, pos, str)) < cout "OK."; >
else < cout "Error"; > >

За бажанням можна змінити введення вхідних даних (ім'я файлу, позиція, рядок заміни).

7. Функція RemoveStringFromFileByIndex(). Видалення рядка з файлу за його номером

Видалення рядка з файлу за його номером можна виконувати за прикладом. 6 (заміна рядка у текстовому файлі).
Загальний алгоритм наступний:

  • прочитати всі рядки файлу масив (список);
  • видалити рядок з масиву;
  • записати модифікований масив назад у файл.

Для формування списку рядків можна використовувати функції GetStringsFromFileC() та GetStringsFromFileS() , які описані у пунктах 3 та 4.

Текст функції видалення рядка за номером наступний.

#include
using namespace std;  // модуль необхідний роботи з файлами
#include
// Функція, що видаляє рядок у файлі за заданим номером,
// Номер рядка починається з 0.
// Параметри функції:
// - filename - ім'я файлу, з якого видаляється рядок;
// - position - номер рядка у файлі, який потрібно видалити.
// Якщо операція пройшла успішно, функція повертає true, якщо
// Рядок не видалено, функція повертає false.
bool RemoveStringFromFileByIndex(string filename,  int position) <  // 1. Перевірка, чи правильно вказаний рядок
if (position < 0)  return false; // 2. Додаткові змінні
string* lines;  // Список рядків
int n;  // кількість рядків у списку (файлі)
// 3. Прочитати кількість рядків у файлі n = CountLinesInFile(filename);  // виклик функції пункту 2
// 4. Перевірка, чи прочитався файл filename
if (n == -1)  return false; // 5. Перевірка, чи коректно значення position
if (position >= n)  return false; // 6. Отримати список рядків lines типу string* n = GetStringsFromFileS(filename, &lines);  // функція пункту 4
// 7. Видалити рядок у позиції position
for (int i = position; i < n – 1; i++) lines[i] = lines[i + 1];  // 8. Зменшити загальну кількість рядків n--;  // 9. Записати список у файл – використовувати функцію SetStringsToFileS()
bool res = SetStringsToFileS(filename, lines, n);  // запис списку
// 10. Звільнити масив lines
if (n > 0)  delete[] lines;  // 11. Повернути результат
return res; >

Використання функції може бути, наприклад, наступним

void main() <  // Видалення вихідного рядка у файлі
string filename = "TextFile1.txt";  // вихідний файл
int pos = 7;  // Вказана позиція рядка
if (RemoveStringFromFileByIndex(filename,pos)) < cout "OK."; >
else < cout "Error"; > >
8. Функція InsertStringToFile(). Вставлення рядка у задану позицію у файлі

Підхід такий самий, як у попередніх пунктах. Потрібно отримати рядки файлу як масиву (тип string чи char *). Потім потрібно вставити рядок у масив та записати змінений масив рядків назад у файл.
Якщо значення позиції вставки дорівнює кількості елементів у файлі, то рядок додається до кінця файлу.

#include
using namespace std;  // модуль необхідний роботи з файлами
#include
// Функція, яка вставляє вказаний рядок у вказану позицію файлу.
// Параметри функції:
// - filename - ім'я файлу;
// - str - рядок, що вставляється;
// – position – позиція рядка str. Нумерується з 0 до кількості рядків у файлі.
// Якщо вставка відбулася вдало, функція повертає true.
bool InsertStringToFile(string filename,  string str,  int position) <  // 1. Оголосити додаткові змінні
int count;  string* lines =  nullptr; // Список рядків файлу
// 2. Отримати список рядків із файлу - виклик функції, описаної в п.4 count = GetStringsFromFileS(filename, &lines);  // 3. Перевірка, чи відбувається нормально читання рядків
if ((count < 0))  return false; // 4. Перевірка, чи коректно значення position.
// Якщо positon==count, то рядок додається до кінця файлу.
if ((position < 0) || (position >count))  return false; // 5. Створити новий список lines2, у якому на 1 елемент більше
string* lines2 =  nullptr; try
< // Спроба виділити пам'ять для масиву lines2 lines2 =  new
string[count+1]; >  catch (bad_alloc e) <  // Якщо спроба виділення пам'яті невдала, завершити програму cout if (Lines! =  nullptr) // звільнити пам'ять
delete[] lines;  return false; >
// 6. Скопіювати lines=>lines2
// 6.1. Спочатку скопіювати до позиції position
for (int i = 0; i <position; i++) lines2[i] = lines[i];  // 6.2. Додати до lines2[position] рядок str lines2[position] = str;  // 6.3. Копіювати наступні рядки
for (int i = position; i < count; i++) lines2[i + 1] = lines[i];  // 7. Збільшити загальну кількість рядків на 1 count++;  // 8. Записати рядки lines у файл
bool res = SetStringsToFileS(filename, lines2, count);  // 9. Звільнити пам'ять, виділену для рядків lines, lines2
if (Lines! =  nullptr) delete[] lines;  if (lines2 !=  nullptr) delete[] lines2;  // 10. Повернути результат
return res; >

Виклик функції InsertStringToFile() до функції main() може бути наступним.

void main() <  // Вставка зазначеного рядка у задану позицію файлу
string filename =  "TextFile1.txt"; // вихідний файл
int pos = 8;  // Вказана позиція рядка
string s =  "Hello"; // рядок вставки
if (InsertStringToFile(filename, s, pos)) < cout "OK."; >
else < cout "Error"; > >
9. Функція SwapStringsInFile(). Обмін місцями двох рядків у файлі

Скорочений алгоритм функції SwapStringsInFile():

  1. Прочитати рядки файлу до списку.
  2. Змінити рядки у списку.
  3. Записати змінений список у файл.

Текст функції обміну рядків є наступним.

#include
using namespace std;  // модуль необхідний роботи з файлами
#include
// Функція, яка змінює місцями два рядки у зазначених позиціях.
// Параметри:
// - filename - ім'я файлу;
// - pos1 – позиція рядка обміну 1 (нумерується з 0);
// - pos2 – позиція рядка обміну 2 (нумерується з 0).
// Якщо обмін пройшов успішно, функція повертає true. Інакше false.
bool SwapStringsInFile(string filename,  int pos1,  int pos2) <  // 1. Перевірка, чи коректні значення pos1, pos2
if ((pos1 < 0) || (pos2 < 0))  return false; // 2. Оголосити додаткові змінні
int count; string* lines =  nullptr; // масив рядків файлу
string s;  // 3. Отримати масив рядків файлу count = GetStringsFromFileS(filename, &lines);  // функція з п.4
// 4. Перевірка, чи відбулося успішне читання з файлу
if (count < 0)  return false; // 5. Перевірка, чи лежать значення pos1, pos2 у межах count
if (pos1> = count)  return false; if (pos2> = count)  return false; // 6. Поміняти місцями рядки lines[pos1] та lines[pos2] s = lines [pos1]; lines[pos1] = lines[pos2]; lines[pos2] = s;  // 7. Записати масив lines назад у файл
bool res = SetStringsToFileS(filename, lines, count);  // 8. Звільнити пам'ять, виділену для масиву lines
if (Lines! =  nullptr) delete[] lines;  // 9. Повернути результат
return res; >

Виклик функції SwapStringsInFile() з функції main() може бути наступним

void main() <  // Обмін місцями двох рядків у файлі
string filename =  "TextFile1.txt"; // вихідний файл
int pos1 = 2;  // вихідна позиція рядка 1
int pos2 = 7;  // Вихідна позиція рядка 2
if (SwapStringsInFile(filename, pos1, pos2)) < cout "OK."; >
else < cout "Error"; > >
10. Функція ReverseStringsInFile(). Реверсування рядків файлу (перестановка рядків файлу у зворотному порядку)

Алгоритм методу наступний:

  • рахувати рядки з файлу та записати їх у масив;
  • обміняти місцями елементи масиву так, щоб рядки масиву розміщувалися у зворотному порядку;
  • записати змінений масив знову у файл

Текст функції ReverseStringsInFile() наступний

#include
using namespace std;  // модуль необхідний роботи з файлами
#include
// Функція, яка звертає рядки файлу у зворотному порядку.
// Параметри:
// - filename - ім'я файлу.
// Якщо операція відбулася успішно, функція повертає true.
bool ReverseStringsInFile(string filename) <  // 1. Оголосити додаткові змінні
int count;  string* lines =  nullptr; string s;  // 2. Вважати рядки з файлу count = GetStringsFromFileS(filename, &lines); // 3. Перевірка, чи вважалися рядки коректно
if (count return false; // 4. Реверсування масиву lines
for (int i = 0; i < count/2; i++) < s = lines[i]; lines[i] = lines[count - i - 1]; lines[count - i - 1] = s; >// 5. Запис масиву lines у файл
bool res = SetStringsToFileS(filename, lines, count);  // 6. Звільнити пам'ять, виділену для масиву lines
if (Lines! =  nullptr) delete[] lines;  // 7. Повернути результат
return res; >

Використання ReverseStringsInFile() може бути, наприклад, наступним

void main() <  // Реверсування рядків файлу
string filename =  "TextFile3.txt"; // вихідний файл
if (ReverseStringsInFile(filename)) < cout "OK."; >
else < cout "Error"; > >
11. Функція SortStringsInFile(). Сортування рядків у файлі

У прикладі демонструється сортування рядків файлу за допомогою способу вставки. Попередньо рядки копіюються до масиву і там сортуються. Потім відсортований масив рядків назад записується у файл.

#include
using namespace std;  // модуль необхідний роботи з файлами
#include
// Функція сортування рядків у файлі шляхом вставки.
// Параметри:
// - filename - ім'я файлу.
// Якщо сортування відбулося коректно, функція повертає true.
bool SortStringsInFile(string filename) <  // 1. Оголосити додаткові змінні
int count;  string* lines =  nullptr; string s;  // 2. Вважати рядки з файлу в масив lines count = GetStringsFromFileS(filename, &lines);  // Функція описана в п.4
// 3. Перевірка, чи коректно вважалися рядки
if (count < 0)  return false; // 4. Сортування рядків у файлі за зростанням методом вставки
for (int i = 0; i < count – 1; i++)  for (int j = i; j >= 0; j--)  if (lines[j] > lines[j + 1]) < s = lines[j]; lines[j] = lines[j + 1]; lines[j + 1] = s; >  // 5. Записати відсортований масив lines у файл
bool res = SetStringsToFileS(filename, lines, count);  // 6. Звільнити пам'ять, виділену для масиву lines
if (Lines! = nullptr) delete[] lines;  // 7. Повернути результат
return res; >

Використання файлу у функції main()

void main() <  // Сортування рядків у файлі
string filename =  "TextFile4.txt"; // вихідний файл
if (SortStringsInFile(filename)) < cout "OK."; >
else < cout "Error"; > >

Пов'язані теми

Як прочитати один рядок із файлу з ++?

Працюючи з текстовими файлами гразо простіше працювати з даними не як із окремими символами, бо як з рядками з допомогою функцій fgets() і fputs() .

Запис текстового файлу

Функція fputs() записує файл рядок, тобто набір символів, який завершується символом '\0'. Вона має наступний прототип:

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

Перший параметр функції - рядок, що записується, а другий - покажчик на файловий потік. Як результат функція повертає невід'ємне ціле число. При помилках у процесі запису повертається значення EOF.

Під час запису рядка нульовий символ '\0' у файл не записується.

Наприклад, запишемо рядок у файл:

#include int main(void) < // рядок для запису char * message = "Hello METANIT.COM!\nAn apple a day keeps the doctor away"; // файл для запису char*filename="data.txt"; // запис у файл FILE * fp = fopen (filename, "w"); if(fp) < // записуємо рядок fputs(message, fp); fclose(fp); printf("File has been written\n"); >>

Запис досить простий: відкриваємо файл на запис і за допомогою виклику fputs(message, fp) записуємо у файл шуканий рядок.

Читання текстового файлу

Функція fgets() зчитує з файлу один рядок і має наступний прототип:

char * fgets (char * s, int n, FILE * sream);

Перший параметр char *s представляє рядок, в який здійснюється зчитування. Другий параметр - число n вказує скільки символів необхідно зчитувати. І третій параметр є файловий потік, з якого проводиться зчитування.

Під час виклику функція зчитує з файлу трохи більше n-1 символів.Функція припиняє читання, коли прочитає n-1 символи або зустріне символ перенесення рядка \n. Усі лічені символи записуються в рядок s, зокрема символ \n. Також кінець кожного рядка дописується нульовий символ '\0'.

При успішному завершенні функція повертає покажчик s, а при помилці або досягненні кінця файлу повертається значення NULL.

Вважаємо дані з вищезаписаного файлу "data.txt":

#include int main(void) < // файл читання char * filename = "data.txt"; // буфер для зчитування даних із файлу char buffer[256]; // Читання з файлу FILE * fp = fopen (filename, "r"); if(fp) < // поки не дійдемо до кінця, зчитуємо по 256 байт while((fgets(buffer, 256, fp))!=NULL) < printf("%s", buffer); > fclose (fp); > >

Тут відкриваємо файл на читання і в циклі зчитуємо з файлу по 256 символів і виводимо їх на консоль за допомогою виклику fgets (cc, 256, fp). Коли дані у файлі закінчаться, функція поверне NULL, і відбудеться вихід із циклу.

Копіювання файлів

Інший приклад роботи з текстовими файлами - копіювання вмісту з одного файлу до іншого:

#include int main(void) < char * filename1 = "data1.txt"; char * filename2 = "data2.txt"; char buffer [256]; FILE * f1 = fopen (filename1, "r"); // файл для читання FILE * f2 = fopen (filename2, "w"); // файл запис if(!f1 || !f2) < printf("Error occured while opening file\n"); >else < // поки не дійдемо до кінця, зчитуємо по 256 байт із файлу f1 while((fgets(buffer, 256, f1))!=NULL) < // записуємо рядок у файл f2 fputs(buffer, f2); printf("%s", buffer); >> fclose(f1); fclose(f2); return 0; >

Схожі статті

  • Яка рослина цвіте один раз у житті
  • Чому Курчата Розкльовують один одного
  • Який тип механізму в годиннику
  • Скільки грам дає один кущ полуниці
  • Як виміряти сатурацію на смарт годинник
  • Як вимкнути захист у реальному часі Windows 10 через командний рядок
  • Як перейти на наступний рядок без введення
  • Як налаштувати годинник на сенсорному годиннику
  • Недавні статті

  • Як бродить зернова брага
  • Що робити якщо не засмагаєш на сонці чому засмага погано лягає на шкіру або перестає прилипати
  • Як швидко зняти гель лак без апарату
  • Як робиться Каті голови
  • Яка гребінець краще для об'єму
  • Чим роблять м'яку покрівлю
  • Чи можна залишати крем для обличчя на ніч
  • Де знаходиться датчик селектора
  • географія нашої діяльності
    вулиця Драгоманова, 27
    вул. Курчатова 1Б
    вул. Міцкевича 130
    вул. Лабунського, 1
    вул. Макарова-Пржевальського
    вул. Толстого 10
    вул. Грушевського 28
    вул. Перший промінь (Черняхівського)
    напишіть нам

    сообщение успешно отправлено
    x