Hi everybody
From time to time I see others, and myself, writing, again, a way to get rid of leading and trailing blanks in a string. When I moved to C++ from C and learned about the great string class, I thought it would bring this two methods (and even the frequent combination of both of them) with it. But it doesn't.
Does anyone knows if there's a good reason for this?. IMHO I think it would be perfectly justified. I know they can be easily implemented but, to me, it make sense to have them as a standard methods in this class.
C++ is maintained and improved by volunteer effort: the reason there are no trim functions for strings is simply that nobody found the time and desire to write a proposal that adds them to the standard library and to oversee its progress.
Actually, the string class is one of those that gets (or has gotten) a lot of attention. Many people consider it bloated as-is.
The string class is specifically as bare-bones as possible, in-line with other standard containers.
Things that manipulate a string (such as trimming, or case-insensitive comparison) are not as simple as people usually think, and don't actually belong in the string class, just as it would be unreasonable for a vector to know how to sort itself.
The string class (as with all standard containers) simply store data, and provide you methods to access it. Nothing more.
Thanks Cubbi and Duos for your answers.
Cubbi, actually, I see I'm less serious about using C++ than I thought becouse I've never heard about that library. But now I do.
Duoas, if what you say is the reason, then I don't understand why there is a set of methods, grouped under the name "modifiers", that perform a lot of operations that imply modifying strings (insert, append, replace, etc. See string reference in this page) which, in turn, end up handling memory, and that, I agree, is far from being easy.
I'm going to learn about boost library. I still think it would be great to have ltrim and rtrim as standard methods given what I said befor.
There are many ways to do it, and OP has already indicated that he is familiar with at least one of them.
The string class itself can do it easily enough -- only it isn't obviously named with "trim":
1 2 3
TRIM LEFT IN-PLACE
s.erase( 0, s.find_first_not_of( delimiters ) );
1 2 3
TRIM LEFT COPY
s.substr( s.find_first_not_of( delimiters ) );
Duoas, if what you say is the reason, then I don't understand why there is a set of methods, grouped under the name "modifiers", that perform a lot of operations that imply modifying strings (insert, append, replace, etc. See string reference in this page) which, in turn, end up handling memory, and that, I agree, is far from being easy.
You are confusing things.
Insert, append, replace, etc are common container operations for any kind of data -- necessary to handle and maintain the data itself.
Things like trim, however, are common only to specialized subsets of data, and are not necessary to manage the data in memory.
I agree that it could be argued that trim is a common operation for string data, particularly as string data is typically textual data. But I'm not so sure the argument is potent enough to justify adding it to the list of things necessary just to manage the container.
In my case, I face the situation of deciding where to place ltrim and rtrim functions to have them available for my projects (I do a lot of string processing coming from keyboard and files and always my first action is cleaning white spaces both leading and trailing). I've a library for them with some other functions but I end up mixing functions that not exactly fit with this ones. I always see them clearly attached to stirng class.
Next solution could be inheriting from string class, but it looks like it's not a good idea:
Yes, JLBorges, that's what I did, although without templates and using standard methods find_first_not_of () and find_last_not_of () instead of begin and end pointers .
My main concern was not about the functions themselves but about where to place them.
Put the functions in a header file, say str_utils.h
1 2 3 4 5 6 7 8 9 10 11 12
#ifndef STR_UTILS_H_INCLUDED_
#define STR_UTILS_H_INCLUDED_
// place the functions here (either inline or static if they are not templated)
// eg.
inline std::string ltrim( const std::string& str )
{
// ....
}
#endif STR_UTILS_H_INCLUDED_
And then, #include "str_utils.h" and use the functions
Yes, that's what I did. Either str_utils.h, console_io.h (which is my case) or any other possibility is what I don't like. My preferred solution would have been just using them the same way I use length (), or erase ().