Printing log messages with varying length fit into screen width I'm writing a simple sanity tool for a simple USB driver.

The customer is directly facing the output so I have to care about how it looks.
The log messages that I need to print are varying length, and they have "[  SUCCESS ]" and "[  FAIL  ]" trailing part too and the middle is filled with dots.

So what I do is calculate the number of dots that should be in the message.
For a example,

#define SCREEN_SIZE_X            80

void print_message(const char* pMsg, bool isPassed)
{
#define SPRINTF_BUFFER_SIZE    1024
    char* sprintfBuffer=(char*) malloc(SPRINTF_BUFFER_SIZE);
    int iLengthMsg = strlen( pMsg);
    const char* strTrailingPart= isPassed?"[  PASSED  ]":\
                     "[  FAILED  ]"; 
    int iLengthTrailingPart=strlen(strTralingPart);
    int iNumDots= SCREEN_SIZE_X - iLengthMsg - iLengthTrailingPart;

    sprintf( sprintfBuffer,pMsg);

    for(int i=0; i&lt; iNumDots; i++)
    {
        sprintf( sprintfBuffer+strlen( sprintfBuffer),\
                  "%c" , '.');
    }

    sprintf(sprintfBuffer+strlen(sprintfBuffer), \
                 strTrailingPart);
    printf( sprintfBuffer);
    free (sprntfBuffer);    
}               


Any better way to do this thing?
Let me assume you're writing in C++ (leaving a quick review of C++ Cish code for the end.)

For clarity I prefer to split code in separate functions, they may be even reused.

void print_message(const std::string&amp; message, bool isPassed)
{
    const std::string result = resolve_result_message(isPassed);
    std::cout &lt;&lt; message &lt;&lt; get_line_padding(message, result) &lt;&lt; result &lt;&lt; std::endl;
}

std::string resolve_result_message(bool isPassed) {
    // Avoid hard-coded strings, move these to constants
    return isPassed ? "[  FAILED  ]" : "[  PASSED  ]";
}

std::string get_line_padding(const std::string&amp; message, const std::string&amp; result) {
    const int requiredPadding = SCREEN_WIDTH - message.length() - result.length();

    if (requiredPadding &lt;= 0)
        return "";

    return std::string(requiredPadding, '.');
}




About original C code:

You have a maximum output size (which, BTW, will be unaligned with other lines) set to SPRINTF_BUFFER_SIZE. Note that if input is bigger than this then your application may crash and you do not perform any check about this. You may want to cut output (in this case just reused SCREEN_SIZE_X + 1 constant).

If you're using a C compiler then do not cast return value of malloc().

sprintf() to print characters is absolutely an overkill, after all this is enough (don't forget to add a NUL character at the end):

for (int start = strlen(sprintfBuffer), i = 0; i &lt; iNumDots; ++i)
    sprintfBuffer[start + i] = '.';


Now you can see it's equivalent to (after checking if iNumDots is positive):

memset(sprintfBuffer + strlen(sprintfBuffer), '.', iNumDots);


If this function isn't invoked by multiple threads you can avoid to allocate/free the buffer each time marking it as static.



If you're working on resource limited environment you may want to avoid unnecessary allocations, for this example let me assume your code is single threaded and message is short enough to fit one line, let me write it in C:

void print_message(const char* message, bool isPassed) {
    static char buffer[SCREEN_WIDTH + 1] = { 0 };

    const char* passed = isPassed ? "[  FAILED  ]" : "[  PASSED  ]";

    memset(buffer, '.', SCREEN_WIDTH);
    memcpy(buffer, message, strlen(message);
    memcpy(buffer + SCREEN_WIDTH - strlen(passed), passed, strlen(passed);

    puts(buffer);
}