С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,814
Записей в блоге: 2

Написать современно

06.11.2025, 13:50. Показов 12454. Ответов 154
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день

Есть такой фрагмент

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const char * singleC = strstr(src, "//");
const char * multiC = strstr(src, "/*");
const char * eol = strstr(src, "\n");
 
const char * min = nullptr;
if (singleC) min = singleC;
if (multiC && (!min || (multiC < min))) min = multiC;
if (eol && (!min || (eol < min))) min = eol;
 
if (!min) return;
 
if (min == singleC) {
 ...
}
 
if (min == multiC) {
 ...
}
 
if (min == eol) {
 ...
}
Бросается в глаза что код примитивный (тупой, убогий, говнокод и.т.п. - как хотите). Кроме того, его можно существенно ускорить.

Хорошо, как написать грамотно, современно? И заодно универсально, чтобы работал не только с char*

Спасибо
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.11.2025, 13:50
Ответы с готовыми решениями:

Каковы современные решения написания программ?
Уже пол года как изучаю с++. За это время решил не мало задачек и перечитал литературы. Писал все...

Как создают современные компьютерные игры?
Интересно, как создают современные компьютерные игры?? То есть на каком языке программирования?? Я...

Современный интерфейс в C++ Builder
Что используют программисты для создания современного интерфейса в C++ Builder XE4? Ведь сейчас,...

154
Гвоздь Задиров
 Аватар для Folian
1718 / 1117 / 337
Регистрация: 25.01.2019
Сообщений: 2,940
01.12.2025, 02:05
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Igor3D Посмотреть сообщение
Это легко проверить
И ещё раз убедиться.
0
Покинул чат.
1132 / 727 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
01.12.2025, 03:11
Цитата Сообщение от Igor3D Посмотреть сообщение
как написать грамотно, современно? И заодно универсально, чтобы работал не только с char*
Igor3D, свои попытки решения этой задачи есть? Хотелось бы увидеть текущий вариант, или хотя бы прототипы функций, которые решали бы задачу - в твоем понимании.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,814
Записей в блоге: 2
01.12.2025, 15:52  [ТС]
Цитата Сообщение от sdf45 Посмотреть сообщение
Igor3D, свои попытки решения этой задачи есть? Хотелось бы увидеть текущий вариант, или хотя бы прототипы функций, которые решали бы задачу - в твоем понимании.
Текущий вариант и (черновой) прототип давно здесь, см пост #16, копирую основное для удобства
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
using TPair = std::pair<size_t, size_t>;    // position + index
 
TPair FindClosestMatch( std::string_view src, const std::vector<std::string_view> & matches )
{
    for (size_t pos = 0; pos < src.size(); ++pos)
        for (size_t idx = 0; idx < matches.size(); ++idx)
            if (src.compare(pos, src.size() - pos, matches[idx]) == 0)
                return TPair(pos, idx);
 
    return TPair(std::string_view::npos, std::string_view::npos);
}
Каких-то попыток "осовременить/обуниверсалить" не предпринимал. Мысли как это сделать - есть конечно, (отчаянно) намекал много раз Хотелось бы послушать умных людей, свое никуда не убежит
0
Покинул чат.
1132 / 727 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
01.12.2025, 20:08
Цитата Сообщение от Igor3D Посмотреть сообщение
универсально, чтобы работал не только с char*
а с чем еще?

Можно отвязаться от строк вообще - работать с множествами, с которыми умеют итераторы STL и что-то делать, перебирая их "вручную", вроде такого схематично:
C++
1
2
3
4
5
6
7
template<class Container>
void foo(Container &&c){
    auto it=std::begin(c);
    while(it != std::end(c))
       std::cout<< *(it++);
    std::cout<< "\n";
}
Однако в STL есть ranges и algorithm (и прочее), где ооочень много всего, типа std::ranges::search , ::find и тд и тп - советую глянуть примеры на сппреференсе. (имхо оно "грамотно, современно и универсально", хз на счет "быстро").
0
Покинул чат.
1132 / 727 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
02.12.2025, 05:42
Наваял из примеров сппреференса...
Выдает первое вхождение подмножества из набора, проверил на некоторых типах - вроде работает.
С std:: vector и ему подобным получилось некрасиво, так как в моем варианте для поиска в контейнере нужен контейнер и приходится набор для поиска оформлять как std:: vector<std:: vector<int>> intNeedles = {{3},{2}}; даже если надо найти одно число Хз как это фиксить, видимо, какой-то хитрый шаблон должен быть - уже не соображаю...
Короче, наверное хрень, - но я бы хотел улучшить (если кто подскажет или укажет на ошибки - заранее спс)
Кликните здесь для просмотра всего текста

с++20
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
#include <iostream>
#include <algorithm>
#include <string>
#include <string_view>
#include <utility>
#include <ranges>
#include <vector>
#include <optional>
#include <format>
 
using ReturnType = std::optional<std::pair<int, int>>;
 
template<class Container, class Needles>
ReturnType foo(Container &&container,  Needles &&needles){
    
    if(!std::ranges::range<Container> || !std::ranges::range<Needles>)
       return std::nullopt;
    
    int end{-1};
    int start = std::distance(std::begin(container), std::end(container));
    
    for(const auto &needle : needles){
        if(auto res = std::ranges::search(container, needle); !res.empty()) {
            const auto first = std::distance(std::begin(container), std::begin(res));
            if(first < start){
                start = first;
                end = std::distance(std::begin(container), std::end(res));;
            }
        }
    }
    if(end > 0)
        return ReturnType{std::pair(start, end)};
    else 
        return std::nullopt;
}
 
 
int main()
{
    auto print = [](std::string_view title, const ReturnType &res){
        std::cout << std::format("{}, from {} to {}\n", title, res.value().first, res.value().second);
    };
   
    //const char* charStr = "somesex text";
    //std::string testString(charStr);
    std::string testString = "somesex text";
    std::vector<std::string> needle = {"ex", "tex", "al"};
    if(auto res = foo(testString, needle))
       print("string", res);
    
    std::string_view testStringView = testString;
    if(auto res = foo(testStringView, needle))
       print("string view", res);
       
    if(auto res = foo("literal", needle))
       print("literal", res);
       
    std::vector<int> intVector = {1,2,3};
    std::vector<std::vector<int>>intNeedles = {{3},{2}}; // кхе кхе :)
    if(auto res = foo(intVector, intNeedles))
       print("int vector", res); 
       
    int intArr1[] = {3,2,1};
    if(auto res = foo(intArr1, intNeedles))
       print("int c array", res);
    
    return 0;
}
Qt
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
//CONFIG += c++20
auto print = [](QString title, const ReturnType &res){
        qDebug() << QString("%1, from %2 to %3")
                        .arg(title)
                        .arg(res.value().first)
                        .arg(res.value().second);
    };
 
    
    QString testString = "somesex text";
    QStringList needle  = {"ex", "xt", "al"};
    if(auto res = foo(testString, needle))
        print("Qt string", res);
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,814
Записей в блоге: 2
02.12.2025, 20:10  [ТС]
Цитата Сообщение от sdf45 Посмотреть сообщение
наверное хрень
Почему хрень? Во всяком случае работает и заслуживает обсуждения. По мелочам
Цитата Сообщение от sdf45 Посмотреть сообщение
if(auto res = std::ranges::search(container, needle); !res.empty())
Повторение ошибки (во всяком случае помарки) стартового поста - это (сам алгоритм) не оптимально по скорости. Об этом говорилось, но найти на 8 листах сложно
Цитата Сообщение от sdf45 Посмотреть сообщение
template<class Container, class Needles>
ReturnType foo(Container &&container,  Needles &&needles){
Тут, возможно, я отстал от моды Почему не простецкая передача по константной ссылке? Разве мы как-то собирались менять container и needles? Точно нет.

Более принципиальные вещи. Задача поддерживать "все что угодно" (типа абсолютная универсальность) не ставилась (хотя и не запрещалась). Как говорилось, есть задача-минимум: поддержка std::string и QString. И если уж мы связываемся с (богомерзкими) темплейтами, то почему бы не пойти по пути наименьшего сопротивления и задействовать std::basic_string_view? Заодно знатоки бы пояснили в чем разница между std::string_view и std::u8string_view. Ну и вообще как юзать std::basic_string_view для QString?

И темплейты имеют свойство резво начинаться, а потом лезут проблемы. Напр
C++
1
2
QString testString = "someSEX text";
QStringList needle  = {"ex", "xt", "al"};
Т.е. поиск с опцией "ignore case". Вроде смешная проблема, но как ее решать в общем случае?

Да, и второй вариант (без темплейт) тоже очевиден, и тоже есть о чем поговорить
0
Покинул чат.
1132 / 727 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
02.12.2025, 23:17
Цитата Сообщение от Igor3D Посмотреть сообщение
(сам алгоритм) не оптимально по скорости
Без понятия... Нужны пруфы.
Цитата Сообщение от Igor3D Посмотреть сообщение
Почему не простецкая передача по константной ссылке?
Можно было и так, сам только учусь - пока нормально не разберусь - считай хз. (В гугле "универсальная ссылка в шаблонах с++").
Надо ли темплейты - холиварная тема,- они мне понравились, буду учить по возможности - но от обсуждения воздержусь.
Цитата Сообщение от Igor3D Посмотреть сообщение
Ну и вообще как юзать std::basic_string_view для QString?
Выше по теме где я зафейлился с временным обьектом, есть примеры... У QString есть конвертеры всякие... А так то, в Qt я бы юзал Qt-сущности пока это возможно.
Цитата Сообщение от Igor3D Посмотреть сообщение
Т.е. поиск с опцией "ignore case". Вроде смешная проблема, но как ее решать в общем случае?
В std:: ranges:: search() добавляют бинарный предикат, переводящий оба аргумента в один кейс, для сравнения.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,814
Записей в блоге: 2
03.12.2025, 00:17  [ТС]
Цитата Сообщение от sdf45 Посмотреть сообщение
В std:: ranges:: search() добавляют бинарный предикат, переводящий оба аргумента в один кейс, для сравнения
Проблема в том что сей предикат будет разным для каждого случая (напр для std::string и QString), и как получить "общий" код - хз. Аналогично перевод строки (или ее части) в число, и.т.д., проблемы с темплейт точно будут

А универсальность без темплейт, стало быть, никому не интересна?
0
Покинул чат.
1132 / 727 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
03.12.2025, 03:19
Цитата Сообщение от Igor3D Посмотреть сообщение
предикат будет разным для каждого случая
ну это да... тогда можно передавать его снаружи.
Кликните здесь для просмотра всего текста

кстати шаблон переписал немного, как это сделано на сппреференсе для std:: ranges:: search()
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
using ReturnType = std::optional<std::pair<int, int>>;
 
template<std::ranges::forward_range Container, std::ranges::forward_range Needles, class Pred = std::ranges::equal_to>
ReturnType foo(Container &&container,  Needles &&needles, Pred pred = {}){
    
    //?
    //if(!std::ranges::range<Container> || !std::ranges::range<Needles>)
    //   return std::nullopt;
    
    int end{-1};
    int start = std::distance(std::begin(container), std::end(container));
        
    for(const auto &needle : needles){
        if (auto res = std::ranges::search(container, needle, pred); !res.empty()) {
            const auto first = std::distance(std::begin(container), std::begin(res));
            if(first < start){
                start = first;
                end=std::distance(std::begin(container), std::end(res));
            }
        }
    }
    if(end>0)
        return ReturnType{std::pair(start, end)};
    else 
        return std::nullopt;
}
 
...
 
    std::string testString = "someSEX  text";
    std::vector<std::string> needle = {"ex", "tex", "al"};
    auto pred=[](auto a, auto b){
        return std::tolower(a) == std::tolower(b);
    };
    if(auto res = foo(testString, needle, pred))
       print("string", res);


чет у меня крепнет ощущение, что фактически переписывая std:: ranges:: search() я занимаюсь фигней и есть более элегантный способ типа такой красоты:
C++
1
2
3
4
5
6
7
    auto const ints = {0, 1, 2, 3, 4, 5};
    auto even = [](int i) { return 0 == i % 2; };
    auto square = [](int i) { return i * i; };
 
    // the "pipe" syntax of composing the views:
    for (int i : ints | std::views::filter(even) | std::views::transform(square))
        std::cout << i << ' ';
Цитата Сообщение от Igor3D Посмотреть сообщение
А универсальность без темплейт, стало быть, никому не интересна?
Делать кучу перегруженных функций под каждый тип, с использованием методов, своих для каждого типа?
(если правильно понимаю, что нужна функция c одним названием, например для std::string, QString, еще чего-то там)
Иначе я не представляю... Какие еще видишь тут варианты?
И откуда хейт на темплейты? Вот в своем варианте ты используешь pair, vector, string_view - это шаблоны.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,814
Записей в блоге: 2
03.12.2025, 10:22  [ТС]
Цитата Сообщение от sdf45 Посмотреть сообщение
чет у меня крепнет ощущение, что фактически переписывая std:: ranges:: search() я занимаюсь фигней
Согласен
Цитата Сообщение от sdf45 Посмотреть сообщение
есть более элегантный способ типа такой красоты:
В чем красота-то? Что многие такого не знают, не используют? Ну "удивить" еще не значит "хорошо"
Цитата Сообщение от sdf45 Посмотреть сообщение
Делать кучу перегруженных функций под каждый тип, с использованием методов, своих для каждого типа? (если правильно понимаю, что нужна функция c одним названием, например для std::string, QString, еще чего-то там) Иначе я не представляю... Какие еще видишь тут варианты?
Ну вот что Вы сделали? Нашли std:: ranges:: search. Так может еще чего-то "найти"? Побогаче, пожирнее. Искать не только в std:: (ладно уж)

Не по теме:

Будете тыкать - перестану отвечать

0
Покинул чат.
1132 / 727 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
03.12.2025, 13:36
Цитата Сообщение от Igor3D Посмотреть сообщение
Так может еще чего-то "найти"? Побогаче, пожирнее. Искать не только в std::
ну если найдете че-нить такое - делитесь, а я хочу разобраться с тем, что есть, - по STL пока нечего добавить, мало практики (про boost вообще молчу).
0
 Аватар для Наталья8
519 / 369 / 66
Регистрация: 09.03.2016
Сообщений: 3,898
03.12.2025, 14:26
Цитата Сообщение от Igor3D Посмотреть сообщение
Побогаче, пожирнее
Ни чё не понял...
Наверное смысл очень высокий.
Для избранных.
Выше моего понимания.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,814
Записей в блоге: 2
03.12.2025, 15:35  [ТС]
Цитата Сообщение от sdf45 Посмотреть сообщение
ну если найдете че-нить такое - делитесь, а я хочу разобраться с тем, что есть,
Вот ссылка что в теме уже приводилась. Читать все необязательно, посмотрите список классов в конце, может что и подойдет
0
Покинул чат.
1132 / 727 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
03.12.2025, 21:40
Цитата Сообщение от Igor3D Посмотреть сообщение
посмотрите список классов в конце, может что и подойдет
Для чего? Эти классы работают в песочнице Qt. Без проблем можно переписать сабж на них, но внутри будут методы Qt и входящие данные (строки) прийдется конвертировать к типам Qt, если это возможно.
Хотя никто не мешает использовать в Qt что нибудь из STL (тем более что в версии 6.10 похоже есть поддержка с++23 -по крайней мере некоторые вещи из STL работают) или другой либы.
Свой (вернее сказать сппреференсовский) вариант я показал: он может принимать std::string, QString и их подвиды, - все, что проходит std::ranges::range<T>
Дальше уже только вам виднее, что в итоге должно получиться и как это реализовать.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,814
Записей в блоге: 2
03.12.2025, 22:31  [ТС]
Цитата Сообщение от sdf45 Посмотреть сообщение
Свой (вернее сказать сппреференсовский) вариант я показал: он может принимать std::string, QString и их подвиды, - все, что проходит std::ranges::range<T>
Не всегда, но часто гораздо приятнее съесть вкусную Qt-плюшку чем пыхтеть со своим великом Ну да ладно, "показал" - так показал, вопросов больше нет
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.12.2025, 22:31
Помогаю со студенческими работами здесь

Нормальная, современная книга по C++ с ООП уклоном
Так вышло что изучаю параллельно два языка Java и C++ ну вот жизть так сложилась нужно писать и там...

А.Александреску - Современное проектирование на C++
Собственно вопрос не совсем по программированию :) Хочу купить бумажный вариант, но смущает, что...

Современный интерфейс в C++ Builder / C++ Builder
Что используют программисты для создания современного интерфейса в C++ Builder 6? Ведь сейчас,...

Каков современный подход для работы со строками
Здравствуйте, хотел узнать современный подход для работы со строками. В С++ так же используется...

Концепция ООП и их использование в современных языках программирования
Дали курсовую на эту тему. Подскажите, какую литературу, которую можно бы было использовать пр ...


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

Или воспользуйтесь поиском по форуму:
155
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru