Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What serious alternatives exist for the IOStream library? (besides cstdio)

Tags:

c++

iostream

I'm looking for a library which operates similar to iostreams, in that it performs conversions, and allows writing to memory buffers, files, and the console. However, I'd like something type safe, as iostream is. Are there any serious libraries which do this?

Being able to specify the output encoding for things would be a plus.

Note that I'm not interested in libraries which simply front iostreams because they just add more complexity to what iostreams is doing, e.g. boost::format.

PreEmptive comment response: I don't want to use cstdio because using that system it's impossible to have code be output location agnostic. That is, you have to call one function for sending things to buffers, and you have to call another function to send things to files, and another for the console, etc.

EDIT2: In response to the flurry of comments below: I'm fed up with both iostreams and cstdio. Here are more specific reasons. I tried to keep my "rant" out of this question, but people keep asking my if I'm off my rocker, so here's my rationale.

cstdio

  • Can't handle Unicode characters correctly
  • Can't write into something like a string without doing manual buffer management
  • Often requires support of nonstandard extensions (e.g. vsnprintf) in order to be usable (EDIT: Okay, C99's standard library being in C++11 adds most/all of these now)
  • Can't change the location of output without changing the original code (nonstandard extensions e.g. in glibc allow you to treat a file pointer as a buffer, which kind of does this... but it's still just that, a nonstandard extension)
  • Makes security "fun" (to the point where entire chapters are dedicated in security docs explaining issues, e.g. with "printf"'s format strings and such)
  • Not type safe

iostreams

  • Slow
  • Entirely too complicated to a client. If you use only what comes with the standard library it's great, but attempting to extend things is next to impossible. I read the entire "Standard C++ IOStreams and Locales" book -- the only book seemingly available on the topic -- twice -- and I still don't know what's going on.

I love iostreams in concept, even the use of operator<< which some people seem to not like, but it seems entirely too over engineered to me. Someone should not have to spend countless hours reading books in order to be a simple client of your library. Sure, if you're adding a new output source or something like that I could understand, but.... clients should be shielded from that complexity. (Isn't that what a library's for?)

This is about the only thing that's painful in C++ that "just works" in other programming languages, that I see no reason to be complicated.

like image 471
Billy ONeal Avatar asked May 30 '11 00:05

Billy ONeal


People also ask

What is the difference between iostream and Cstdio?

cstdio is the header file that contains all of the old C functions to print stuff and write to files (printf(), fprintf(), fopen(), etc). iostream contains all of the C++ streams to do that same thing (more easily IMO).

What is known as iostream library?

The iostream library is an object-oriented library that provides input and output functionality using streams. A stream is an abstraction that represents a device on which input and ouput operations are performed.

Is iostream a C++ library?

Header files available in C++ for Input/Output operations are: iostream: iostream stands for standard input-output stream. This header file contains definitions of objects like cin, cout, cerr, etc.


1 Answers

The {fmt} library: I just stumbled across it from a YouTube talk and it seems to be quite nice.

A formatting facility based on {fmt} has been proposed for standardization in C++20: P0645. Both P0645 and {fmt} use a Python-like format string syntax which is similar to printf's but uses {} as delimiters instead of %.

For example

#include <fmt/core.h>  int main() {   fmt::print("The answer is {}.", 42); } 

prints "The answer is 42." to stdout.

The std::format function proposed for C++20:

#include <format>  int main() {   std::string s = std::format("The answer is {}.", 42); } 

Notable features of {fmt}:

  1. Type and memory safety with errors in format strings optionally reported at compile time.

  2. Extensibility: users can write formatters for their types, including custom format specification parsers (as in Python).

  3. Compact binary code. The print example above compiles to just:

    main: # @main   sub rsp, 24   mov qword ptr [rsp], 42   mov rcx, rsp   mov edi, offset .L.str   mov esi, 17   mov edx, 2   call fmt::v5::vprint(fmt::v5::basic_string_view<char>, fmt::v5::format_args)   xor eax, eax   add rsp, 24   ret .L.str:   .asciz "The answer is {}." 

    which is comparable to printf and much better than iostreams.

  4. Performance: {fmt} is considerably faster than common implementations of printf and iostreams. Here are results from a tinyformat benchmark on macOS with clang:

    ================= ============= =========== Library           Method        Run Time, s ================= ============= =========== libc              printf          1.01 libc++            std::ostream    3.04 {fmt} 1632f72     fmt::print      0.86 tinyformat 2.0.1  tfm::printf     3.23 Boost Format 1.67 boost::format   7.98 Folly Format      folly::format   2.23 ================= ============= =========== 
like image 53
smoothware Avatar answered Oct 04 '22 16:10

smoothware