Я хотел бы иметь возможность создать механизм ведения журнала, который очень просто передает аргументы в printf, но мне нужна подсветка синтаксиса и проверка ввода. Это схема для пространства имен Log
, которое у меня есть.
#pragma once
#include "pch.h"
namespace Log
{
// Determines whether to create the console window or not.
// Turn off for before release.
extern bool CreateConsoleWindow;
// Initialisation.
extern bool Init();
// Writes a line to the console, appended with \r\n.
extern void WriteLine(const char* _Format, ...);
// Writes a line to the console, with a [Debug] prepend.
extern void DebugInfo(const char* _Format, ...);
// Writes a line to the console, with a [Server] prepend.
extern void ServerInfo(const char* _Format, ...);
// Destruction.
extern bool Dispose();
}
Это моя реализация для Log::WriteLine(_Format, ...)
:
// Writes a line to the console, appended with \r\n.
void WriteLine(const char* _Format, ...)
{
// Print the message.
char buffer[4096];
va_list args;
va_start(args, _Format);
auto rc = vsnprintf(buffer, sizeof(buffer), _Format, args);
va_end(args);
// Append the new line.
printf("\r\n");
}
Но когда я это делаю, я теряю вся проверка и подсветка синтаксиса, которые необходимы, будучи новичком, из входной строки. Например:
auto hash = Crypto::GetHash(syntax[1].c_str()); // unsigned long, by way of multiple nested macros.
printf("Hash: %d", hash);
Это будет показывать %d
светло-зеленым, и в printf
будет предупреждение о hash
, говорящее, что оно не будет отображаться, потому что оно ожидает %lu
. Я полагаюсь на VS, чтобы научить меня, что я делаю неправильно, чтобы я мог учиться на своих ошибках.
Если я сделаю то же самое с моей функцией:
auto hash = Crypto::GetHash(syntax[1].c_str()); // unsigned long, by way of multiple nested macros.
Log::WriteLine("Hash: %d", hash);
Тогда %d
такой же коричневый, как и остальная часть строки, и ошибки проверки нет.
Эти две вещи важны. Есть ли способ сделать эту работу правильно? Я новичок в C ++ после десятилетнего опыта. NET, и кривая обучения огромна. Я думал, что начну с основ, просто с простой системы регистрации, чтобы я мог видеть, что выводится в любое время, чистым и элегантным способом. В C# это заняло бы всего пару минут, но в C ++ теперь, спустя четыре часа, у меня открыто около 40 вкладок в трех windows из Firefox, и я все еще разбиваю моя голова против каждой кирпичной стены, с которой можно столкнуться.
Я пытался определить макрос внутри пространства имен:
#define WriteLine(_Format, ...) printf(_Format, __VA_ARGS__)
Но он говорит, что не может найти printf. Я пытался украсить _Printf_format_string_
:
extern int _cdecl DebugInfo(_Printf_format_string_ const char* _Format, ...);
Но это не имеет значения. Я пытался __attribute__((format(printf, 1, 2)))
extern void WriteLine(const char* _Format, ...) __attribute__((format(printf, 1, 2)));
Но это вызывает массу ошибок в ожидании {
, unexpected identifier
и expected a declaration
, но не говорит, где и почему, или как.
Я слишком много спрашиваю в C ++, для такого базового c запроса?