This page is a rough comparison between the Vstr string library and other string libraries that I've seen. This may be somewhat biased, due to the fact that I wrote the Vstr library ... then again it is better :). For a comparison of printf() like functions see this page.
Rich API, full printf() implementation including custom formatters. For more detail see the other pages on this site.
This library tries to do something similar to what Vstr does. The major differences are that:
Also, due to conforming to the std::string C++ API, it isn't possible to act with a substring of a Rope, you can only make a copy of a substring using the substr call (however that substring makes everything internal references). Vstr doesn't have a true distinction between the entire Vstr and a portion thereof.
This is probably the most used C string library, and comes with the glib utility library. This works on a simple start pointer and length, model. This makes it much more memory effiecient for small strings. This feature also makes it pretty much impossible to do IO into the strings, share data between strings and kills performance on substitutions. Failure to allocate memory calls abort().
The printf implementation calls the host implementation of sprintf/asprintf/etc. if it looks like a valid C99 implementation, and uses the trio library internally otherwise (this is only true as of version 2.2.0 though -- before that it'll just crash in some instances). So it's impossible to have custom formatters (the most obvious annoying fallout of this is that you can't add a GString to a GString as part of a printf() call) and portability is a problem (Although it is supposed to be valid to work with data that has NIL bytes in it doing so loses data in certain cases -- I've submitted a patch for the last problem).
There is no substitution API in glib, probably because you can't share data so you just do a memcpy() and an overwrite. It's also worth noting that your program may crash if you try and add data in a GString to the GString itself.
Note that vstr_split_chrs() and other functions for using a GString are in glib, as part of the C string helper functions (Eg. g_strsplit() in the case of vstr_split_chrs()). There is also limited support in glib for doing things in ASCII regardless of the current user locale.
This library is a slightly saner version of the ISO C str* functions, with a few extentions. It works with (char *) as the native type, and doesn't do automatic allocation ... so buffer overflows are still a concern.
The printf implementation is internal and based on the Apache snprintf() function, '\'' (thousand modifiers), 'a', 'F', 'Lf', 'lld', 'td', 'zd', 'hhd' , etc. and i18n format parameter modifiers are all completly missing Unspecified precision is broken, as is corner cases for octal etc. also infinity/nan output is not correct with regard to case. Buffer overflows are possible in the integer formatting paths You can have custom modifiers, but only triggered on the system '%' character ... so gcc will currently spam warnings. It also looks like the ISO C std. is completely ignored for certain corner cases. Also note that due to the fact that the strings cannot be resized by the library the printf implementation uses a snprint() interface, this means that data can be lost using the interface if the programer isn't carefull.
This library works with (char *) as the base type, although all allocator functions are also passed a "pool" that the (char *) comes from, and so resizing can be done by the library.
By version 1.4.1 there is a printf like function, however it uses the system asprintf() call if it is available, and if not it just calls snprintf() with a limit of 256 characters (so data may be truncated even though the interface doesn't imply that). It does declare a "vector" type that is roughly equivalent to a Vstr_sects type however it only contains a "ptr" to the data ... so doing a split on a string involves at least doing a memdup() (it actually does a strndup()).
Major namespace corruption, for example by using the string function you'll get definitions for "pool" and "vector"; Also the constructor functions tend to have names like "new_pool", "new_subpool" and "new_vecotr" as well as "pool_register_malloc" and "vector_push_back" etc. There are also lots of uses of macro functions in lower case, for instance vector_push_back() is a macro function calling _vector_push_back() (which also violates ISO 9899:1999 7.1.3/1 "All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces."
This is a bunch of add on functions to the std. C string functions, inspired by PHP.
This library doesn't allow "binary" (!isgraph && !isspace -- so changes depending on global locale) characters. Printf like function calls the host implementation. Has a large API for add, find, delete and substitue. A couple of other APIs for reverse, uppercasing and lowercasing.
An interesting library, it uses an opaque type for the string which is suitably non simplistic internally to allow quite a few opimisations. The function names all obey the 6 character C89 identifier limit (a limitation Vstr completely ignores so as to be more consistant, and hopefuly more readable). It's not obvious if it would use more or less memory than Vstr ... my guess is more, but then I'm biased.
It uses (void *) in most places and takes either a C string or an (sz *) [the internal opaque type]. It distinguishes between these by a 2 character magic constant, so if you try and use a C string with that constant life becomes interesting. There is no printf like function.
This has a fairly well abstracted namespace, esp. considering it is
only bundled with the
It is somewhat ammusing that even though this isn't a string library, it is much better than most of the other string libraries here.
This is the string implementation that comes with the Boehm Garbage Collector (and so is included in gcc etc.). It pretty much requires a GC as you can't "alter" a string, only make a new string with the alterations in it. Sharing data is a main point of this implementation, however again it isn't possible to do things directly on a "substring" you must first create that substring as a first class string.
Although the basic APIs are there, add/del/sub/etc. there are few added functions to help you deal with the strings (although it does provide something equivilent to vstr_sc_read_len_file() but it uses stdio, and there isn't any good way to deal with IO errors).
Also note that the printf implementation just calls the host implementation of sprintf/asprintf/etc. directly for anything that isn't one of the 's', 'r', 'c' or 'n' format specifiers. The custom format specifier of 'r' is the only one possible and will make gcc barf warnings if you use it. It also doesn't allow i18n argument number specifiers. This is an "old" implementation though, with the last copyright from 1994 so some of these problems probably stem from that.
This is a set of functions used in the
It is upto the user of the library whether you have a fixed or dynamically sized buffer, and I think you can return failure if memory isn't available but the vstream.c and vstring.c implementations just assumes this can't happen. The functions to act on the buffer are just copied APIs of ISO C (FILE *) manipulators, str* and mem* (with the addition of memcat()). Importantly there are no interfaces for removing data or substituting data in the string (you could probably do remove from the end of the string easily by playing with the pointers and counters, but you'd have to write your own function for it). There is no way to access anything but the entire string, using the API, or add data anywhere but the end of the string.
There is an interface for using netstrings, but instead of the simple begin and end semantics in Vstr the interface overloads the string interface ... so you have to say netstring_memcpy( ... ) which will copy data and encapsulate it as a netstring. It's also worth noting that the counters are of type "int", and the negative bit is used in the code ... so it's not possible to have a string bigger than INT_MAX.
The printf like functions are implemented by parsing the format string and then passing known good formats through to the host implementation sprintf() (after requesting enough space to hold them). It doesn't accept long long or long doulbe types, i18n argument number specifiers or thousand seperator modifiers.
Similar implementation to glib, however there are a lot more utility functions for finding data dna comparing strings. There are really two string APIs, one for strings (Autostr) and one fo "dynamic buffers" (Autobuf) ... these type would be interchangable apart from the fact that the members are ordered differently in their structure definitions. Autobuf's can handle data with NIL bytes in it, while Autostr calls the ISO C str*() functions dna silently fails. Both string types share features, however the Autostr API has a few more functions. This library is now unmaintained, according to the original author.
Like glib printf() like function calls the host seperately for each % token after calculating the max possible size of that tokens output. It doesn't include '\'' (thousand modifiers), 'A', 'a', 'td', 'zd' and i18n format parameter modifiers. However they will be equally unportable everywhere.
Note that there are static extentions to the printf() like function so that you can print the Autostr string type.
Again, C++ ... uses a pointer and length model but allows reference counting on entire QString objects. This means that an assignment of an entire string from a to b will share most of the storage, but a substring or altering any part of either object will nullify all sharing. The printf like function has an internal implementation for parsing the format string (which doesn't allow i18n argument number specifiers -- or even l ll h hh size modifiers), but it also calls out to the host sprintf() implementation for numbers, pointers and doubles.
C++ ... uses a pointer and length model but allows reference counting the Dwtring objects. This means that an assignment of an entire string, or a substring from a to b will share most of the storage, but altering any part of either object will nullify all sharing. Apart from that it is much like QString in the QT library.
Has a start pointer and length model, however it does grow the strings itself ... and call abort() is the allocations fails. However, note that altough it includes a bad snprintf() implementation (see below) it doesn't have a sprintf() call to write into the "spif string". typedef's and macro's appear to be used just to make the code less readable. It has an "interesting" set of APIs, mainly due to the overhead of adding data to a string or getting a substring. For instance you can "splice" part of a string and another string, but you can't substitue data inside a string without copying it multiple times.
The fact that almost all searching/comparing APIs map onto C library APIs means that embeded NIL characters silently fail -- even though there are APIs to initialise strings from a file descriptor.
It has terrible abuse of the namespace, outside of the string.c file however it looks like you could seperate the string.c code out without a lot of work -- at which point the namespace is well contained (but it also is built assuming that you'll be using the "spif" object model -- however this doesn't seem to be a requirement).
The printf() like function is a version of Patrick Powell's snprtinf() with a really bad version of a floating point formatter added to it (see below for the Samba version which is slightly better version of Patrick's code with floating point).
This library has allocating versions of most of the std. modifying str*() library functions. It has a specialised version of strspn() for matching "C identifier" like names. It also has a couple of utility functions for reading IO ... however blocking is mandatory, and speed may be a problem due to numerous realloc() calls for large datasets.
The printf() like function just calls the host implementation. Note that before 2003-02-25 the failure path was broken, and would crash.
Has a start pointer and length model, but it doesn't allocate/reallocate memory itself. So the user has to do half the work of the library to pre-allocate the right ammount of data before using the functions. The printf like function has almost no resemblence to the ISO printf function, which is bound to confuse the user. It provides a function to do a read, which is nice. Also has a simple "parse configuration file" function.
This library is a slightly saner version of the ISO C str* functions, with a few extentions. It works with (char *) as the native type, and doesn't do automatic allocation ... but almost all functions are size limited so buffer overflows aren't a big concern, but losing data is. The library has some vector functions, but it uses (char **) as the vector type and alters the original string in it's verison of split.
This is a reimplementation of the functions in qmail, but under a GPL license. It does have a stralloc set of calls that operate on a start pointer and length model, they do dynamically reallocate memory and pass memory failure back to the caller. As with all DJB code though, the API is written as a set of small atomic operations. For instance printf like functionality is implemented over 12 different functions named fmt_* (which don't check for overflows, but some are also reimplemented as a as stralloc functions). This design makes using the API much more clumsy, for a minor speedup, makes doing i18n almost impossible and goes directly against "premature optimization is bad".
It's worth nothing that although the stralloc functions deal with dynamic memory a lot of the other function ignore bounds checking and/or assume things are terminated with a '\0' character. Even more so than the DJB functions, although this is probably bad just implementation rather than deliberate -- but then why would you think you can write good code with an interface when the implementor can't (for instance the scan_long and scan_8long functions are almost completely broken in libowfat ... but fine in qmail).
This library works on a simple start pointer and length, model. It is mostly a subset of the glib functionality, and like glib also calls abort() on memory errors. One of the obvious missing pieces is a printf() like function.
The namespace isn't terrible, apart from the fact that the identifiers "xmalloc", "xrealloc" and "xfree" are all defined and exported from the library (which is compiled shared, but given a static library ".a" suffix).
This is currently just a C++ wrapper class around a (char *), with a couple of extra functions not available in std. C. It does to auto matic resizing. It also look looks like the implementation could be changed to fix a lot of problems with this (Eg. the length is calculated using strlen(), so embeded '\0' characters corrupt data) without affecting source compatability. The printf like function calls the host implementation.
This is a C++ library designed to be compatible with the string library that comes with the Microsoft Foundation Classes. Each character in the string is actually a class itself. This could probably be fixed without changing source compatability.
For a comparison of "portable" printf() like functions, you should look at this page
Any corrections or omissions you see in the above, feel free to contact me at the address below