Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't C++ reimplement C standard functions with C++ elements/style?

Tags:

c++

c

stl

For a specific example, consider atoi(const std::string &). This is very frustrating, since we as programmers would need to use it so much.

  1. More general question is why does not C++ standard library reimplement the standard C libraries with C++ string,C++ vector or other C++ standard element rather than to preserve the old C standard libraries and force us use the old char * interface?

    Its time consuming and the code to translate data types between these two interfaces is not easy to be elegant.

  2. Is it for compatible reason,considering there was much more legacy C code than these days and preserving these C standard interfaces would make translation from C code to C++ much easier?

  3. In addition,I have heard many other libraries available for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?

PS: Considering much more answers to the first specific question, I edit a lot to clarify the question to outline the questions that I am much more curious to ask.

like image 713
Jichao Avatar asked Nov 20 '09 15:11

Jichao


2 Answers

Another more general question is why do not STL reimplementate all the standard C libraries

Because the old C libraries do the trick. The C++ standard library only re-implements existing functionality if they can do it significantly better than the old version. And for some parts of the C library, the benefit of writing new C++-implementations just isn't big enough to justify the extra standardization work.

As for atoi and the like, there are new versions of these in the C++ standard library, in the std::stringstream class.

To convert from a type T to a type U:

T in;
U out;
std::stringstream sstr(in);
sstr >> out;

As with the rest of the IOStream library, it's not perfect, it's pretty verbose, it's impressively slow and so on, but it works, and usually it is good enough. It can handle integers of all sizes, floating-point values, C and C++ strings and any other object which defines the operator <<.

EDIT:In addition,I have heard many other libraries avaliable for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?

Boost has a boost::lexical_cast which wraps std::stringstream. With that function, you can write the above as:

U out = boost::lexical_cast<U>(in);
like image 196
jalf Avatar answered Oct 25 '22 12:10

jalf


Even in C, using atoi isn't a good thing to do for converting user input. It doesn't provide error checking at all. Providing a C++ version of it wouldn't be all that useful - considering that it wouldn't throw and do anything, you can just pass .c_str() to it and use it.

Instead you should use strtol in C code, which does do error checking. In C++03, you can use stringstreams to do the same, but their use is error-prone: What exactly do you need to check for? .bad(), .fail(), or .eof()? How do you eat up remaining whitespace? What about formatting flags? Such questions shouldn't bother the average user, that just want to convert his string. boost::lexical_cast does do a good job, but incidentally, C++0x adds utility functions to facilitate fast and safe conversions, through C++ wrappers that can throw if conversion failed:

int stoi(const string& str, size_t *idx = 0, int base = 10);
long stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);
long long stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);

Effects: the first two functions call strtol(str.c_str(), ptr, base), and the last three functions call strtoul(str.c_str(), ptr, base), strtoll(str.c_str(), ptr, base), and strtoull(str.c_str(), ptr, base), respectively. Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

Returns: the converted result.

Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if the converted value is outside the range of representable values for the return type.

like image 39
Johannes Schaub - litb Avatar answered Oct 25 '22 11:10

Johannes Schaub - litb