Search code examples
cconsole

gcc Console output newline


I am trying to output to the console starting on a fresh new line, as in, if the line before did not end with a \n then output \n before outputting the given string.

I came up with this, that seems to work ok.

#include <stdio.h>

bool newLine = true;
void Output(const char* str)
{
    while(*str)
    {
        putchar(*str++);
    }
    if (*(str-1) == '\n')
    {
        newLine = true;
    }
    else
    {
        newLine = false;
    }
}
void OutputN(const char* str)
{
    if (!newLine)
    {
        putchar('\n');
        newLine = true;
    }
    Output(str);
}
int main()
{
    for (int i = 0; i < 10; i++) { Output("."); }
    OutputN("01");
    Output ("23");
    Output (""); // test to see if a blank string works ok
    OutputN("45");
    Output ("67\n");
    Output (""); // test to see if a blank string works ok after \n
    Output ("89");
    for (int i = 0; i < 10; i++) { Output("."); }
    Output ("\n");
    Output(".");
}

reference this thread "C puts() without newline" there is comment that reads "It works but could be quite inefficient if stdout is not buffered." referring to calling putchar repeatedly in a loop. I amuse to do with buffering and flushing.

my question is, under what circumstances would this become inefficient and is it likely to cause me any problems.

I plan to call this Output generally in place of fputs(str, stdout); 1 on a raspberry pi 5 ruining kdle, and 2 (possibly more likely to have efficiency issues) from a raspberry pi pico that streams its output over serial.


Solution

  • Instead of looping, use puts() to write the whole string. Then check if the last character is a newline.

    You should also check for an empty string, and not do anything. Your code will access outside the array if the string is empty, causing undefined behavior.

    void Output(const char* str)
    {
        if (str[0] == '\0') { // empty string
            return;
        }
        fputs(str, stdout);
        newLine = str[strlen(str)-1] == '\n';
    }