Работа со строками в c и C++

Я не уверен, как именно передать различные типы строк в функции в C.

У меня есть функция, которая получает отформатированную строку

void Logger::info(const char *logstring, ...) 
{

    // So I basically can write a preliminary message "DATA:" to a buffer
    // and then use vsnprintf() to write the const char *logstring to the buffer as well.

    int offset = 0;
    va_list argp;
    char buf[STRSIZE + 1];

    va_start(argp, logstring);
    offset = sprintf(buf, "DATA: ");
    vsnprintf(&buf[offset], STRSIZE - offset, logstring, argp);
    va_end(argp);

    // Then I write the buffer to stderr

    fprintf(stderr, "%s\n", buf);
}

То, что я хотел бы сделать, это переместить все это глубже в функцию. Но я не могу заставить его работать, потому что понятия не имею, как успешно передать отформатированную строку "logstring" в функцию и заставить ее выйти на другую сторону.

Поэтому я хочу сделать это так...

info(const char *logstring, ...)
{
    writeToFile("Data:",logstring);
}

Тогда я могу сделать запись файла журнала более централизованно.

1 ответ

Решение

Хорошо, очень вероятно, что я не понял, где вы ищете, но готов сделать снимок и записать ответ. Далее приведено описание базового средства ведения журнала, которое вы можете получить, но демонстрирует, как централизовать сборку сообщений. Внизу приведены некоторые условия тестирования, и я намеренно уменьшил начальный размер буфера, чтобы вы могли пройти в отладчике и увидеть изменения в интерактивном режиме. Вы, несомненно, захотите оценить это.

В любом случае, если мне повезло, и я правильно понял вопрос, я надеюсь, что если он не решит вашу проблему напрямую, вы хотя бы получите некоторые идеи. Благодарю.

РЕДАКТИРОВАТЬ: OP запросил подавить с помощью std::string и изменения размера буфера, чтобы обеспечить соответствие ограниченным возможностям компиляции его встроенной системной среды. Поэтому используются буферы фиксированной длины и выводятся из vsnprintf() доверяют только если контент действительно подходит.

#include <stdio.h>
#include <stdarg.h>
#include <string.h>

class Logger
{
    static const size_t STRSIZE = 256;

public:
    void error(const char* fmt, ...)
    {
        va_list argptr;
        va_start(argptr,fmt);
        log("ERROR", fmt, argptr);
    };

    // two different logging interfaces.
    void info(const char* fmt, ...)
    {
        va_list argptr;
        va_start(argptr,fmt);
        log("INFO", fmt, argptr);
    };

    void debug(const char* fmt, ...)
    {
        va_list argptr;
        va_start(argptr,fmt);
        log("DEBUG", fmt, argptr);
    };

private:
    void log(const char *msg, const char* fmt, va_list& vl)
    {
        // uses a fixed size message buffer
        char str[STRSIZE+1] = {0};
        strncpy(str, msg, sizeof(str)-1);
        strncat(str, ": ", (sizeof(str)-1) - strlen(str));

        // needed for sizing limits of variadic printf, then send
        //  output as a single line message to stderr.
        size_t mlen = strlen(str);
        if (vsnprintf(str + mlen, sizeof(str)-mlen-1, fmt, vl) >= 0)
            fprintf(stderr, "%s\n", str);
        else
            fprintf(stderr, "%s: (max log message length exceeded)\n", msg);
    };
};

int main(int argc, char *argv[])
{
    Logger logger;

    logger.debug("Numbers %d %d %d", 1,2,3);
    logger.error("Strings %s %s %s", "1", "2", "3");
    logger.info("Mixed %s %d %p", "1", 2, "3");
    logger.info("No additional parameters required for this message.");

    // demonstrate automatic cutoff.
    char sbig[] = "0123456789012345678901234567890123456789"
                  "0123456789012345678901234567890123456789";

    logger.debug("Oversized params: %d-%s %d-%s %d-%s %d-%s", 
                 1, sbig, 2, sbig, 3, sbig, 4, sbig);
    return 0;
}
Другие вопросы по тегам