Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
florgas
5 / 4 / 0
Регистрация: 28.09.2010
Сообщений: 345
#1

Как регулярно считывать последнюю строку в файле - C++

30.10.2013, 22:44. Просмотров 426. Ответов 3
Метки нет (Все метки)

Добрый день. Имеется текстовый файл. Он постоянно обновляется и в его конец дописываются строки. Необходимо считывать новую строку непосредственно в string, как только она появляется в файле. Вот и вопрос: как это реализовать? Считывать все по порядку до последней строки - не самая лучшая идея, ибо файл может быть большим и это не самый оптимальный вариант. А вот как сразу считать последнюю строку. И тут же вопрос, как отловить добавление новых строк в файл? У меня мысли разве что взять последнюю строку и постоянно ее сравнивать с последней. Если они станут различными, значит была добавлена новая строка в файл. Надеюсь вопрос понятен. Спасибо.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.10.2013, 22:44
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как регулярно считывать последнюю строку в файле (C++):

Удалить последнюю строку в файле (или сохранить файл без них) - C++
Читаю текстовое поле чужого приложения, заношу содержимое в файл, из файла читаю последнюю строку. Проблема в том, что в конец файла...

Как считывать строку с пробелами? - C++
Стоит такая задача: Во введенной строке символов (последний - $) подсчитать общее количество цифр и букв S. Программа была написана и...

Как считывать большую строку по частям? - C++
Как считывать большую строку по частям?

Как на экран вывести последнюю строку матрицы - C++
Си или С++

Не хочет считывать второй раз строку - C++
Здравствуйте, пытаюсь работать с базой данных (в виде *.txt). Мои действия: 1) создаем базу данных, название вводим без ".txt" (1) 2)...

Как перейти на новую строку в файле - C++
Итак, у меня есть некоторый вопрос насчёт считывания из файла некоторых данный. Вообщем текстовые строки у меня берутся хорошо через...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
DiffEreD
1430 / 767 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
31.10.2013, 01:54 #2
Могу предложить такое решение (с использованием boost):
C++
1
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <conio.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
#include <windows.h>
 
namespace fs = boost::filesystem;
using input = std::istreambuf_iterator<char>;
 
int main()
{
   SetConsoleCP (1251); SetConsoleOutputCP (1251);
 
   fs::path path("D:/file.txt");
   if(!fs::is_regular_file(path))
   {
      std::cout << "Файла не существует или неверно задано его имя!" << std::endl;
      return EXIT_FAILURE;
   }
 
   std::ifstream ifs(path.string());
   if(!ifs.is_open())
   {
      std::cout << "Не удалось открыть файл для чтения!" << std::endl;
      return EXIT_FAILURE;
   }
 
   auto last_modified = fs::last_write_time(path);
 
   std::vector<std::string> lines;
   std::string text{input(ifs), input()};
   auto pos = ifs.tellg();
   ifs.close();
 
   boost::split(lines, text, boost::is_any_of("\n"), boost::token_compress_on);
   for(std::string& s : lines) std::cout << s << std::endl;
 
   std::vector<std::string> new_lines;
 
   while(true)
   {
      //ждем 5 секунд и проверяем не изменился ли файл:
      std::this_thread::sleep_for(std::chrono::seconds(5));
      if(last_modified != fs::last_write_time(path))
      {
         last_modified = fs::last_write_time(path);
         std::cout << "\n***** Файл был изменен. *****\n" << std::endl;
         ifs.open(path.string());
         ifs.seekg(pos);
         text.assign((input(ifs)), input()).erase(0, 1); //erase удаляет первый '\n'
         pos = ifs.tellg();
         ifs.close();
         std::cout << text << std::endl;
         boost::split(new_lines, text, boost::is_any_of("\n"), boost::token_compress_on);
 
         std::copy(new_lines.begin(), new_lines.end(), std::back_inserter(lines));
      }
      if(kbhit())
         break;
   }
 
   std::cout << "\n\n\n***** Все строки: *****" << std::endl;
   for(std::string& s : lines) std::cout << s << std::endl;
 
   return 0;
}
0
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
31.10.2013, 13:12 #3
Цитата Сообщение от florgas Посмотреть сообщение
как отловить добавление новых строк в файл?
В качестве критерия можно использовать размер файла. Запомним sz - размер файла. Если размер увеличился, значит, начиная с позиции sz записана новая строка( или несколько новых строк). Для перемещения указателя на позицию sz можно использовать функцию fstream::seekg().
0
florgas
5 / 4 / 0
Регистрация: 28.09.2010
Сообщений: 345
01.11.2013, 21:42  [ТС] #4
Цитата Сообщение от DiffEreD Посмотреть сообщение
Могу предложить такое решение (с использованием boost):
C++
1
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <conio.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
#include <windows.h>
 
namespace fs = boost::filesystem;
using input = std::istreambuf_iterator<char>;
 
int main()
{
   SetConsoleCP (1251); SetConsoleOutputCP (1251);
 
   fs::path path("D:/file.txt");
   if(!fs::is_regular_file(path))
   {
      std::cout << "Файла не существует или неверно задано его имя!" << std::endl;
      return EXIT_FAILURE;
   }
 
   std::ifstream ifs(path.string());
   if(!ifs.is_open())
   {
      std::cout << "Не удалось открыть файл для чтения!" << std::endl;
      return EXIT_FAILURE;
   }
 
   auto last_modified = fs::last_write_time(path);
 
   std::vector<std::string> lines;
   std::string text{input(ifs), input()};
   auto pos = ifs.tellg();
   ifs.close();
 
   boost::split(lines, text, boost::is_any_of("\n"), boost::token_compress_on);
   for(std::string& s : lines) std::cout << s << std::endl;
 
   std::vector<std::string> new_lines;
 
   while(true)
   {
      //ждем 5 секунд и проверяем не изменился ли файл:
      std::this_thread::sleep_for(std::chrono::seconds(5));
      if(last_modified != fs::last_write_time(path))
      {
         last_modified = fs::last_write_time(path);
         std::cout << "\n***** Файл был изменен. *****\n" << std::endl;
         ifs.open(path.string());
         ifs.seekg(pos);
         text.assign((input(ifs)), input()).erase(0, 1); //erase удаляет первый '\n'
         pos = ifs.tellg();
         ifs.close();
         std::cout << text << std::endl;
         boost::split(new_lines, text, boost::is_any_of("\n"), boost::token_compress_on);
 
         std::copy(new_lines.begin(), new_lines.end(), std::back_inserter(lines));
      }
      if(kbhit())
         break;
   }
 
   std::cout << "\n\n\n***** Все строки: *****" << std::endl;
   for(std::string& s : lines) std::cout << s << std::endl;
 
   return 0;
}
Это все хорошо, но слишком сложно. Можно проще: считывать постоянно последнюю строку в файле и проверять ее с последней строкой в файле, которая была записана ранее в отдельную строку. Если строка изменила, т.е. стала не равна, то файл изменился.
Вопрос лишь в том, как прочитать конкретно последнюю строку?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.11.2013, 21:42
Привет! Вот еще темы с ответами:

Как найти строку Чили в текстовом файле ? - C++
и 1 вывести ее на консоль 2 вывести ее столицу Например в текстовом файле список стран Канада Оттава США Вашимгтон Мексика...

Как в файле сделать переход на новую строку - C++
Подскажите, пожалуйста, как произвести дозапись в файл с новой строки. Файл открыт через fopen

Как найти нужную строку в txt файле? - C++
Как найти нужную строку в txt файле из программы на C++. С помощью fstream. Заранее спасибо!

Как изменить определенную строку в текстовом файле? - C++
Я создаю программу Contacts. У каждого контакта есть свои данные: id, name... и т.д. Но это не важно. После завершение добавление контактов...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
01.11.2013, 21:42
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru