Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
Эндрю23
2 / 2 / 2
Регистрация: 20.10.2011
Сообщений: 119
1

Считать строки из файла, изменить и записать в другой файл

20.12.2016, 15:02. Просмотров 1231. Ответов 8
Метки нет (Все метки)

Добрый день.
Есть входящий файл:
Кликните здесь для просмотра всего текста
Лицевой счёт 1010047078 показания счётчика (9243)
1010029116 6036
Ао НЭСК
1010004047 167490
1010008075 Т1- 6764; Т2- 2810
1010006568. День 8985 . Ночь 3180
101 0064019.12881
1010068144.73212
1010065077 6850
1010029133/04306
Л/С 1010010156 15358
1010022093. 2433
1010021040. 11003
1010053128- 23006
1010006025 40590
итд


Необходимо преобразовать его в
Кликните здесь для просмотра всего текста

1010004047;2016-10-01;167490;;;
1010029116;6036;;;
1010004047;167490;;;
1010008075;6764;2810;;
итд


Подскажите как такое можно реализовать?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.12.2016, 15:02
Ответы с готовыми решениями:

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

Написать программу: считать две матрицы из файла и записать их в другой файл
считать две матрицы из файла и записать их в другой файл. Добавлено через 3 часа 26 минут...

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

Из текстового файла считать вторую строку и последнюю. Записать их в другой текстовой файл
Из текстового файла считать вторую строку и последнюю. Записать их в другой текстовой файл. Прошу...

Считать текст из файла и записать в другой только строки, не содержащие определенных символов
Всем привет, кто может помочь с решением данной задачи, буду очень благодарен. "Написать...

8
Peoples
1377 / 859 / 757
Регистрация: 06.02.2016
Сообщений: 2,275
Записей в блоге: 18
Завершенные тесты: 5
20.12.2016, 15:19 2
На самом деле логика прослеживается слабо
Я так понимаю выводится номер счёта и показания только?
1
Эндрю23
2 / 2 / 2
Регистрация: 20.10.2011
Сообщений: 119
20.12.2016, 15:38  [ТС] 3
Первый список это экспорт СМС с номером счета и показаниями, сообщения присылают каждый как ему вздумается.
Во втором списке файл, который воспринимается программой для расчета потребителей. Собственно, чтобы не вбивать каждый счет из списка1 необходимо сформировать список2, который автоматически затягивается программой.
0
Peoples
1377 / 859 / 757
Регистрация: 06.02.2016
Сообщений: 2,275
Записей в блоге: 18
Завершенные тесты: 5
20.12.2016, 16:00 4
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
#include <iostream>
#include <string>
#include <fstream>
#include <regex>
#include <algorithm>
#include <sstream>
#include <iterator>
#include <vector>
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void refu(string &);
void reblanck(string &);
void onfile(vector<string>&v,ofstream &fd);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main() {
    ifstream ff("tr.txt");
    vector<string> v;
    string s;
    while(!ff.eof()) {
        getline(ff,s);
        refu(s);
        if(!all_of(s.begin(),s.end(),[](char &c) {
        return c==' ';
    })) {
            stringstream ss(s);
            string result;
            for(string s1; ss>>s1;) {
                result+=s1+" ";
            }
            v.push_back(result);
        }
    }
    ff.close();
    for_each(v.begin(),v.end(),reblanck);
    ofstream fd("res.txt");
    onfile(v,fd);
    fd.close();
    return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void refu(string &s) {
    replace_if(s.begin(),s.end(),[](char &c) {
        return !isdigit(c);
    },' ');
}
void reblanck(string &s) {
    auto f=s.find(' ');
    if(f!=string::npos && f<10) {
        s.erase(f,1);
    }
}
void onfile(vector<string>&v,ofstream &fd) {
    for(vector<string>::iterator iter=v.begin(); iter!=v.end(); iter++) {
        cout<<*iter<<endl;
        fd<<*iter<<endl;
    }
}
1
20.12.2016, 16:00
MrGluck
Форумчанин
Эксперт CЭксперт С++
8121 / 4973 / 1436
Регистрация: 29.11.2010
Сообщений: 13,456
20.12.2016, 16:13 5
Цитата Сообщение от Эндрю23 Посмотреть сообщение
2016-10-01
А это откуда взялось?

Такой алгоритм подойдёт?
1) каждая строка обрабатывается как отдельная запись о Л/С и его состоянии
2) ищем лицевой счёт - 10 подряд идущих цифр
3) любой другой набор цифр воспринимаем как показания, передаём их в том формате, в каком они встретились.
Есть нюансы - если Л/С кто-то указал через пробелы, если имеется несколько показаний, их могут записать в произвольном порядке. Никто же не запрещает сначала дать показания за счетчик Т2/Ночь, а потом Т1/День.
0
Peoples
1377 / 859 / 757
Регистрация: 06.02.2016
Сообщений: 2,275
Записей в блоге: 18
Завершенные тесты: 5
20.12.2016, 16:25 6
В местах с T оставалась цифра, поправил
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
#include <iostream>
#include <string>
#include <fstream>
#include <regex>
#include <algorithm>
#include <sstream>
#include <iterator>
#include <vector>
using namespace std;
/////////////////////////////////////////////////////////////////////////////////
void refu(string &);
void reblanck(string &);
void onfile(vector<string>&,ofstream &);
void normal(string &);
///////////////////////////////////////////////////////////////////////////////////
int main() {
    ifstream ff("tr.txt");
    vector<string> v;
    string s;
    while(!ff.eof()) {
        getline(ff,s);
        refu(s);
        if(!all_of(s.begin(),s.end(),[](char &c) {
        return c==' ';
    })) {
            stringstream ss(s);
            string result;
            for(string s1; ss>>s1;) {
                result+=s1+" ";
            }
            v.push_back(result);
        }
    }
    ff.close();
    for_each(v.begin(),v.end(),reblanck);
    for_each(v.begin(),v.end(),normal);
    ofstream fd("res.txt");
    onfile(v,fd);
    fd.close();
    return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////
void refu(string &s) {
    replace_if(s.begin(),s.end(),[](char &c) {
        return !isdigit(c);
    },' ');
}
void reblanck(string &s) {
    auto f=s.find(' ');
    if(f!=string::npos && f<10) {
        s.erase(f,1);
    }
}
void onfile(vector<string>&v,ofstream &fd) {
    for(vector<string>::iterator iter=v.begin(); iter!=v.end(); iter++) {
        cout<<*iter<<endl;
        fd<<*iter<<endl;
    }
}
void normal(string &s) {
    for(string::iterator iter=s.begin(); iter!=s.end(); iter++)
        if(*prev(iter)==' ' && *next(iter)==' ') {
            s.erase(prev(iter),next(iter));
        }
}
1
Эндрю23
2 / 2 / 2
Регистрация: 20.10.2011
Сообщений: 119
20.12.2016, 16:37  [ТС] 7
Да, там в списке 1 еще есть дата, но можно хотя бы без нее
Кликните здесь для просмотра всего текста
Лицевой счёт 1010047078 показания счётчика (9243) 01.12.2016 18:54
1010029116 6036 02.12.2016 10:41
Ао НЭСК 02.12.2016 14:16
1010004047 167490 02.12.2016 17:13
1010008075 Т1- 6764; Т2- 2810 02.12.2016 22:11
1010006568. День 8985 . Ночь 3180 04.12.2016 14:28
101 0064019.12881 05.12.2016 14:49
1010068144.73212 05.12.2016 14:50
1010065077 6850 05.12.2016 17:24
1010029133/04306 06.12.2016 11:07
Л/С 1010010156 15358 06.12.2016 13:14
1010022093. 2433 06.12.2016 20:37
1010021040. 11003 06.12.2016 20:38
1010053128- 23006 06.12.2016 22:01
1010006025 40590 07.12.2016 8:27
Этот абонент доступен для звонка. 07.12.2016 11:43
Им: Кайырбеков Стас Телефон: *+79183999329‬ 07.12.2016 11:48
1010066209 06216 07.12.2016 16:24
1010006372 11100 07.12.2016 19:40
Л.с1010047060 пок.с. 3872 08.12.2016 7:16
16800 08.12.2016 8:37
1010053058 (12367)показания 08.12.2016 12:28


Такой алгоритм вполне подошел бы.
Там еще нюанс в том, что счетчик бывает однофазный и двухфазный, 1 или 2 состояния для одного Л/С (просто показания или показания день/ночь).
Ну а прочие нюансы можно не рассматривать, я так полный список просмотрел, подобных отклонения практически нет, несколько строчек таких только. А еще есть строки, в которых вообще никаких упоминания о Л/С, например, "Вам звонил такой-то...".
0
MrGluck
Форумчанин
Эксперт CЭксперт С++
8121 / 4973 / 1436
Регистрация: 29.11.2010
Сообщений: 13,456
20.12.2016, 18:19 8
Лучший ответ Сообщение было отмечено Эндрю23 как решение

Решение

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
#include <fstream>
#include <iostream>
#include <regex>
#include <string>
 
int main()
{
    std::ifstream ifs("input.txt");
    if (!ifs)
        return 1;
    //std::ofstream out("output.txt");
    std::string line;
    while (std::getline(ifs, line))
    {
        // извлекаем дату
        size_t pos1 = line.rfind(' '), pos2 = line.rfind('\t', pos1-1);
        if (pos2 == std::string::npos)
            continue;
 
        const std::string date = line.substr(pos2 + 1, pos1 - pos2 - 1);
        line.erase(pos2);
 
        std::smatch sm;
        std::regex_search(line, sm, std::regex("\\d{10,10}"));
        const std::string account = sm.str();
        if (account.empty())
            continue;
 
        std::vector<std::string> counters;
        std::regex reg("\\d{2,10}");
        for (auto it = std::sregex_iterator(line.begin(), line.end(), reg); it != std::sregex_iterator(); ++it)
            if (account != it->str())
                counters.push_back(it->str());
        if (counters.empty())
            continue;
 
        std::cout << account << ';' << date << ';';
        for (const auto &c : counters)
            std::cout << c << ';';
        for (size_t i=counters.size(); i < 3; i++)
            std::cout << ';';
        std::cout << std::endl;
    }
}
1
Эндрю23
2 / 2 / 2
Регистрация: 20.10.2011
Сообщений: 119
22.12.2016, 08:26  [ТС] 9
MrGluck, большое спасибо, все работает прекрасно. Чуть-чуть доделал, чтобы происходила запись в файл
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
#include <fstream>
#include <iostream>
#include <regex>
#include <string>
 
int main()
{
    std::ifstream ifs("input.txt");
    if (!ifs)
        return 1;
    std::ofstream ifd("output.txt");
    std::string line;
    while (std::getline(ifs, line))
    {
        size_t pos1 = line.rfind(' '), pos2 = line.rfind('\t', pos1-1);
        if (pos2 == std::string::npos)
            continue;
 
        const std::string date = line.substr(pos2 + 1, pos1 - pos2 - 1);
        line.erase(pos2);
 
        std::smatch sm;
        std::regex_search(line, sm, std::regex("\\d{10,10}"));
        const std::string account = sm.str();
        if (account.empty())
            continue;
 
        std::vector<std::string> counters;
        std::regex reg("\\d{2,10}");
        for (auto it = std::sregex_iterator(line.begin(), line.end(), reg); it != std::sregex_iterator(); ++it)
            if (account != it->str())
                counters.push_back(it->str());
        if (counters.empty())
            continue;
        
        std::cout << account << ';' << date << ';';
        ifd << account << ';' << date << ';';
        for (const auto &c : counters) {
                std::cout << c << ';';
            ifd << c << ';';
        }
       for (size_t i=counters.size(); i < 3; i++) {
            std::cout << ';';
            ifd << ';';
        }
        ifd << '\n';
    std::cout << std::endl;
    }
    ifd.close();
    system("pause");
}
0
22.12.2016, 08:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.12.2016, 08:26

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

Считать текст из файла и записать его в другой файл, заменив каждую первую букву слов
Доброго времени суток Нуждаюсь в помощи. Есть задание: программа должна считывать английский...

Считать данные из текстового файла по условию и записать их в другой текстовый файл (файловый ввод/вывод)
Здравствуйте! Очень прошу о помощи! Суть задания - дан текстовый файл, нужно считать его и записать...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

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