Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
 Аватар для florgas
6 / 5 / 0
Регистрация: 28.09.2010
Сообщений: 366

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

30.10.2013, 22:44. Показов 1234. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Имеется текстовый файл. Он постоянно обновляется и в его конец дописываются строки. Необходимо считывать новую строку непосредственно в string, как только она появляется в файле. Вот и вопрос: как это реализовать? Считывать все по порядку до последней строки - не самая лучшая идея, ибо файл может быть большим и это не самый оптимальный вариант. А вот как сразу считать последнюю строку. И тут же вопрос, как отловить добавление новых строк в файл? У меня мысли разве что взять последнюю строку и постоянно ее сравнивать с последней. Если они станут различными, значит была добавлена новая строка в файл. Надеюсь вопрос понятен. Спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.10.2013, 22:44
Ответы с готовыми решениями:

Как прочесть последнюю строку в текстовом файле
Слушайте ребят Это опять я помогите мне сделать такую хренатень чтоб а ладно смотритре program file; uses crt; var a:string; ...

Во всех словах заменить первую букву на последнюю, а последнюю на первую. Как считывать каждое слово?
Ребята, написал программу, выполняла свое предназначение, но меня преподаватель попросил записать в строку 2 слова, и программа считывает...

Перейти на последнюю строку в файле
Есть файл в котором несколько строк...как мне перейти на последнюю строку для работы именно с ней(например поиска в ней подстроки)?

4
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
31.10.2013, 01:54
Могу предложить такое решение (с использованием 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
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
31.10.2013, 13:12
Цитата Сообщение от florgas Посмотреть сообщение
как отловить добавление новых строк в файл?
В качестве критерия можно использовать размер файла. Запомним sz - размер файла. Если размер увеличился, значит, начиная с позиции sz записана новая строка( или несколько новых строк). Для перемещения указателя на позицию sz можно использовать функцию fstream::seekg().
0
 Аватар для florgas
6 / 5 / 0
Регистрация: 28.09.2010
Сообщений: 366
01.11.2013, 21:42  [ТС]
Цитата Сообщение от 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
0 / 0 / 0
Регистрация: 05.04.2019
Сообщений: 19
21.04.2019, 11:56
Цитата Сообщение от DiffEreD Посмотреть сообщение
Могу предложить такое решение (с использованием boost):
Использовал данный код предложенный DiffEreD. Все работает спасибо. Но выход из программы осуществляется через нажатие любой клавиши (kbhit()). Мне потребовалось другая логика выхода из цикла - от последнего обновления файла включается счетчик и через 10 минут выйти из программы чтения файла. Если в течении этих 10 минут файл был обновлен, то заново запускать счетчик.
Я набросал код но он работает не так как я хотел. То есть файл читается 10 минут и программа выходит. Файл продолжает обновляться и дальше а мы вышли. Вот сижу туплю уже третий день ничего не могу придумать. Может кто поможет решить проблему.

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
76
77
78
79
80
81
82
83
84
85
86
87
#include "pch.h"
#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>
#pragma warning(disable : 4996)
 
namespace fs = boost::filesystem;
using input = std::istreambuf_iterator<char>;
 
int main()
{
    
    setlocale(LC_CTYPE, "rus");
 
    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);
    float timer = 600; // Время работы таймера в секундах
    auto start = std::chrono::high_resolution_clock::now(); // Присваиваем auto start время последней модификации
 
    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); 
            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));
            auto start = last_modified; // пересваеваем новое значение последнего обнавления
        }
        auto finish = std::chrono::high_resolution_clock::now();
        std::chrono::duration<float> elapsed = finish - start; // Определяем разницу если значение больще "timer" выходим
        if (elapsed.count() > timer) {
            break;
        }
 
        if (kbhit())
            break;
    }
 
    std::cout << "\n\n\n***** Все строки: *****" << std::endl;
    for (std::string& s : lines) std::cout << s << std::endl;
 
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.04.2019, 11:56
Помогаю со студенческими работами здесь

Найти последнюю строку в текстовом файле
Как найти последнюю строку в текстовом файле ?

Получить самую последнюю длинную строку в файле
Ребят помогите пожалуйста, вот задачка: Дан текстовый файл получить самую последнюю длинную строку. Благодарю за внимание :)

Удалить последнюю пустую строку в текстовом файле
Здравствуйте. Искал очень долго решение, но ничего не нашел и сделать не вышло. Есть файл .txt в нем нужно удалить 2ю строку, она...

В текстовом файле поменять местами первую и последнюю строку
В заданном текстовом файле поменять местами первую и последнюю строку. Результат вывести в другой файл

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


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru