Search code examples
cmicrobenchmarkputs

fputs() with newline like puts() in C


In C, puts(string); will print string to stdout, followed by a newline. fputs(fileptr, string);, on the other hand, will write string to fileptr without the trailing newline. Is there any function like fputs() that appends a newline, or should I stick with fprintf(fileptr, "%s\n", string); like I've been using?

fputs() seems more efficient than fprintf() to me as it doesn't parse it's input. I know I could also use

fputs(string, fileptr);
fputc('\n', fileptr);

but I was wondering if there was a way to do that with one disk write.

I tried to figure out how puts() appends the newline (since printf() is really just a wrapper for vfprintf(stdout, ...), I thought the same might hold true for puts() and fputs()), but I oddly cannot find puts() in the glibc source.


Solution

  • I was wondering if there was a way to do that with one disk write.

    You're over-optimizing things. The writing to disk is buffered, unless you happened to mess with the buffering settings or you're using a really bad libc implementation. In general, the best way to achieve what you want is

    fputs(string, fileptr);
    fputc('\n', fileptr);
    

    hands down. If you wouldn't care about optimization, or you believe your compiler would optimize it, you can use

    fprintf(fileptr, "%s\n", string);
    

    it would need to parse the format string - and even then, internally, use the equivalent of fputs to write the %s and fputc to print the newline.


    However there is one gotcha - be aware that the FILE structure usually has some kind of locking for thread safety. fputs + fputc would require acquiring the lock twice, whereas fprintf would probably do it just once. In a single-threaded application the lock wouldn't be contested, however. But it might just be that for a complicated format and multithreaded program, the fprintf parsing is faster than acquiring the locks for separate operations. Another is that a call from another thread can interleave the fputs/fputc, but fprintf is supposed to be atomic.


    P.S. the puts code of Glibc is in libio/ioputs.c.