Теперь номерация Логов стала проще и быстрее !
Пользуйтесь, если кому-то надо ! ) ![]()
Пользуйтесь, если кому-то надо ! )
__LINE__
Проверил ...
PrintFormat("(__LINE__) MEAS rot=900 max_tw=%d max_th=%d line_h=%d n=%d shift_y=%d => w_final=%d h_final=%d", max_tw, max_th, line_h, n, shift_y, w_final, h_final);
Результат:
2026.01.13 16:11:49.476 (EURUSD,M5) (__LINE__) MEAS rot=900 max_tw=685 max_th=13 line_h=14 n=10 shift_y=70 => w_final=203 h_final=260
... но в другом варианте:
Print(__LINE__); PrintFormat("(__LINE__) MEAS rot=900 max_tw=%d max_th=%d line_h=%d n=%d shift_y=%d => w_final=%d h_final=%d", max_tw, max_th, line_h, n, shift_y, w_final, h_final);
всё получилось:
2026.01.13 16:15:02.898 (EURUSD,M5) 416 2026.01.13 16:15:02.898 (EURUSD,M5) (__LINE__) MEAS rot=900 max_tw=646 max_th=13 line_h=14 n=4 shift_y=70 => w_final=131 h_final=260
... т.е. "416" - это действительно НОМЕР СТРОКИ !
... но тогда возникает вопрос:
"КАК номеровать" логи - чтобы номер строки был именно в строке с логом ?! (особенно для "PrintFormat")
... Нашёл ответ ...
PrintFormat("(стр.%d): MEAS rot=900 max_tw=%d max_th=%d line_h=%d n=%d shift_y=%d => w_final=%d h_final=%d", __LINE__, max_tw, max_th, line_h, n, shift_y, w_final, h_final); Результат: 2026.01.13 16:30:57.628 (EURUSD,M5) (стр.423): MEAS rot=900 max_tw=685 max_th=13 line_h=14 n=10 shift_y=70 => w_final=203 h_final=260
"КАК номеровать" логи - чтобы номер строки был именно в строке с логом ?! (особенно для "PrintFormat")
Можно и так:
PrintFormat("("__LINE__") MEAS rot=900 max_tw=%d max_th=%d line_h=%d n=%d shift_y=%d => w_final=%d h_final=%d", max_tw, max_th, line_h, n, shift_y, w_final, h_final);
Если код разбит на достаточно компактные функции, то может быть удобнее выводить не номер строки кода, а название функции или метода с помощью макроса __FUNCTION__:
PrintFormat(__FUNCTION__" | Scale = %.2f", coeff);
Или использовать их вместе:
PrintFormat(__FUNCTION__" ("__LINE__") | Scale = %.2f", coeff);
Можно и так:
Если код разбит на достаточно компактные функции, то может быть удобнее выводить не номер строки кода, а название функции или метода с помощью макроса __FUNCTION__:
Или использовать их вместе:
... Как вариант - ДА, благодарю за комбо !)
... но порой бывает так, что функция находится в середине кода, а её вызов происходит в "конце" кода, и там могут быть "собрание логов" с разных функций, типа:
--------- Сборная инфа : --------- * вызвали №1 ... * позиция объекта 'такая-то' ... и т.д. ----------------------------------
поэтому __FUNCTION__ придётся пользоваться или "очень умело", или что-то в случае "сборных логов" -->> в комментах сразу (для себя) писать название функций которые в итоге и отображают в "сборных логах" свои результаты!
Например в разных функциях я пишу НЕ "Print..." , а :
AddToLog(StringFormat("...текст..." , переменные , значения которых нужно показать в "Сборном логе"));
и потом есть специальная функция:
//+------------------------------------------------------------------+ //| AddToLog - Добавление строки в лог | //+------------------------------------------------------------------+ void AddToLog(string text) { int size = ArraySize(logLines); ArrayResize(logLines, size + 1); logLines[size] = text; // НЕ выводим в Print - только в массив для метки на скрине } // ← НОВОЕ: Функция для вывода в журнал void PrintToLog(string text) { Print(text); }
(которая собирает логи со всего кода, где-бы они нибыли, чтобы потом в функции "вызова" - отобразить логи (с разных частей кода) сразу в одном Блоке : "сборный лог") :
// ========== ВЫВОДИМ ДЕТАЛЬНЫЙ ЛОГ В ЖУРНАЛ ========== //<<-- строка 2848 PrintToLog("=========================================="); PrintToLog(">>> ПАРАМЕТРЫ ДЛЯ СКРИНЕРА (из Панели):"); PrintToLog("=========================================="); PrintToLog(StringFormat("g_PanelScreenWidthMode = %s", g_PanelScreenWidthMode)); //<<-- из Функции #4 PrintToLog(StringFormat("g_PanelBarsForScreenshot = %d", bars_count_param));//<<-- из Функции # 25 PrintToLog(StringFormat("g_PanelScalePointsPerBar = %d", scale_param));//<<-- из Функции # 38 PrintToLog(StringFormat("g_PanelUseBorders = %s", g_PanelUseBorders ? "TRUE" : "FALSE")); PrintToLog("=========================================="); PrintToLog(StringFormat("Коррекция Окно/Ratio = %d px", g_PanelWindowWidthCorrection)); //<<-- из Функции #55 PrintToLog(StringFormat("Коррекция Границы = %d px", g_PanelBordersWidthCorrection)); //<<-- из Функции #56 PrintToLog("=========================================="); PrintToLog(">>> СКРИНЕР ВЫЗВАН ИЗ ПАНЕЛИ <<<"); PrintToLog("=========================================="); if(g_BtnSignalState) PrintToLog(">>> СИГНАЛ <<<"); PrintToLog(mode_text); PrintToLog(StringFormat("Размеры: %d x %d px (коррекция +%d)", width_px, height_px, correction)); PrintToLog(StringFormat("Баров в скрине: %d", actual_bars)); if(scale_param > 0) PrintToLog(StringFormat("Масштаб: %d п/бар (ЗАДАН ВРУЧНУЮ)", scale_param)); //<<-- из Функции #74 else PrintToLog("Масштаб: с графика (автоматический)"); //<<-- из Функции # 75 PrintToLog(StringFormat("Папка: %s", symbol_folder)); //<<-- из Функции # 88 PrintToLog("==========================================");
... и в логах вижу финальный результат:
========================================== >>> ПАРАМЕТРЫ ДЛЯ СКРИНЕРА (из Панели): ========================================== g_PanelScreenWidthMode = RATIO_WINDOW g_PanelBarsForScreenshot = 0 g_PanelScalePointsPerBar = 0.00000 g_PanelUseBorders = FALSE ========================================== Коррекция Окно/Ratio = 150 px Коррекция Границы = 150 px ========================================== >>> СКРИНЕР ВЫЗВАН ИЗ ПАНЕЛИ <<< ========================================== Режим: 'Окно' Размеры: 1795 x 924 px (коррекция +150) Баров в скрине: 412 Масштаб: с графика (автоматический) (стр.3349) Папка: Screenshots\EURUSD ==========================================
... как видно - такая "сборка лого" намного компактнее, чем отображать все Логи "каждый в моменте вызова" со ссылкой на строку "функции откуда вызвался Лог", п.ч. тогда будет перемешка всех логов, и среди пачки нумерованных логов не сразу найдёшь нужную информацию ! ...
По сути - Ваше предложение на счёт применения : PrintFormat(__FUNCTION__" ("__LINE__")
интересное , и даже в моей "сборке логов" оно МОЖЕТ найти применение ! ... я подумаю над этим!
Спасибо за идею ! )
Мне кажется, вы с ИИ-помощником немного перемудрили. Если судить по тому коду, что вы показали, то видно следующее:
- функция AddToLog() не используется нигде, поэтому может быть удалена;
- функция PrintToLog() не делает ничего, кроме вызова функции Print(), поэтому может быть удалена и заменена вызовом функции Print()
- вызов функции Print(StringFormat("строка с параметрами", [значения параметров, ...])) эквивалентен вызову PrintFormat("строка с параметрами", [значения параметров, ...]).
функция AddToLog() не используется нигде, поэтому может быть удалена;
... на самом деле - всё зависит от "поставленной задачи" !
Если мы разрабатываем , например - простой индикатор ZZ, то нам важно видеть ГДЕ "барахлит" (в какой строке кода согласно логам), поэтому AddToLog тут не подходит, достаточно обычного Print / PrintFormat с номерацией строк кода (__LINE__),
а в моём случае (просто уталю ваше любопытство о том - ГДЕ применялась функция AddToLog) - нужно было действительно делать "засечки логирования" в РАЗНЫХ фрагментах кода, и потом собирать "разрозненные" логи и показывать их в одном узком блоке - для наглядности картины - ЧТО происходило внутри кода в разных процессах ! (именно в разных параллельных ПРОЦЕССАХ) ! и именно для таких вот целей - функция AddToLog как раз пригодилась очень великолепно !
... Кстати именно AddToLog () помогла выявить много "причин" которые давали "некорректные работы", так как мы в одном блоке логов прекрасно видели РАЗНЫЕ результаты, и их легко было сравнить и проанализировать, чем искать те-же данные среди сотен разрозненны строк логов !
Так-что AddToLog () - это "дело вкуса" и поставленной задачи ))
... на самом деле - всё зависит от "поставленной задачи" !
Если мы разрабатываем , например - простой индикатор ZZ, то нам важно видеть ГДЕ "барахлит" (в какой строке кода согласно логам), поэтому AddToLog тут не подходит, достаточно обычного Print / PrintFormat с номерацией строк кода (__LINE__),
а в моём случае (просто уталю ваше любопытство о том - ГДЕ применялась функция AddToLog) - нужно было действительно делать "засечки логирования" в РАЗНЫХ фрагментах кода, и потом собирать "разрозненные" логи и показывать их в одном узком блоке - для наглядности картины - ЧТО происходило внутри кода в разных процессах ! (именно в разных параллельных ПРОЦЕССАХ) ! и именно для таких вот целей - функция AddToLog как раз пригодилась очень великолепно !
... Кстати именно AddToLog () помогла выявить много "причин" которые давали "некорректные работы", так как мы в одном блоке логов прекрасно видели РАЗНЫЕ результаты, и их легко было сравнить и проанализировать, чем искать те-же данные среди сотен разрозненны строк логов !
Так-что AddToLog () - это "дело вкуса" и поставленной задачи ))
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Итак, в процессе программирования я столкнулся с потребностью "писать номера строк" в Логах ! чтобы читая Журнал Логов - ориентироваться не только на показатели Логов, а и видеть: НОМЕР СТРОКИ особо-важных Логов !!!
Сперва это делал тупо-глупо ВРУЧНУЮ, например:
Print("DEBUG START (строка 2828): ExecuteInformFromPanel()");
...но потом перебирать 3500+ строк кода и заменять все устаревшие номера строк на новые - согласитесь - ДОЛГО и НЕУДОБНО !!!
Тогда , будучи пользователем ЧатаGPT я его начал телебонить - КАК по маркерам в текстовой строки - сделать АВТО-ЗАМЕНУ старого номера строки на новый ?!
ЧатаGPT честно ответил что АВТОМАТИЧЕСКИ этого сделать НЕЛЬЗЯ !
Но в Notepad++ есть возможность написать скрипт, который будет искать "шаблон" (например: "строка 1234") и менять <старое число > на <новое число > (т.е. обновлять номера строк) !
...порекомендовал поставить плагин "NppExec" , написал с десяток скриптов ... но увы - всё оказалось сложно и неработало ... потом сменили кирилицу (строка) на латиницу (stroka) но и это НЕ ПОМОГЛО !!!
Потом Искусственный Импровизатор предложил: можно попробовать сделать РУЧНОЙ ПОИСК/ЗАМЕНА ... и дал ВОЛШЕБНУЮ комбинацию для поиска "шаблона" и замены старого номера строки на новый !!!
... в сухом остатке после теста - пишу годный Лайфхак на случай если кому-то вдруг тоже надо (!?!)
Шаг 1 - подготовка:
1) Сперва весь наш код из MetaEditor4-5 загоняем в Notedad++ и генерим номера строк В НАЧАЛЕ строки:
Ctrl+A – выделить всё !
ALT+C – Текст для вставки (задаём "пробел" - это даст пробел между номером строки и строкой) –> Ок
Ctrl+A – выделить всё !
ALT+C – Число для вставки : Исходное число: 1, Увеличение на: 1 –> Ок
(после каждой операции – ПЕРЕВЫДЕЛЯТЬ ВЕСЬ текст для корреткной генерации).
Шаг 2 - работа по обновлению строк ВНУТРИ вашего текста:
2) … после номерации строк: через Поиск/Замену выполняем п.4 (ниже),
3) После перенумерации номеров строк В ЛОГАХ – перед возвращением кода в MetaEditor -->> обязательно удаляем номера строк В НАЧАЛЕ строк (чтобы компилятор кода не ругался на пустые числа в начале строк):
(!) Основной процесс по обновлению номеров строк в Логах:
4) Один проход “обновить любые стр.N”
Ctrl+H (Поиск / Замена):
Поиск (+поставить галочку "Регуляр.выражен."):
^(\s*)(\d+)([^\r\n]*?\bстр\.)\d+([^\r\n]*)(\R?)
Заменить на:
\1\2\3\2\4\5
Это:
· сохраняет ведущие пробелы \1,
· сохраняет номер слева \2,
· меняет число после str. на \2,
· сохраняет конец строки \5 (чтобы не было склеек).
результат:
Было:
616 Print(StringFormat("PPB (стр.720): возврат отложен до ПОСЛЕ скриншота (oldScalePtPerBar=%s oldPointsPerBar=%.5f)",
стало:
616 Print(StringFormat("PPB (стр. 616): возврат отложен до ПОСЛЕ скриншота (oldScalePtPerBar=%s oldPointsPerBar=%.5f)",
Теперь номерация Логов стала проще и быстрее !
Пользуйтесь, если кому-то надо ! )