C++ fixed length string class?
Is there anything like this in Standard C++ / STL? Ideally it should be constructed like
fstring s = fstring(10);
I need to somet开发者_如何学JAVAimes construct or have a string of fixed size. Sometimes to be able to read / write only that many characters into a stream.
Edit:
Note that the size is only known at runtime, and is different from one to the other. But all of the fstring
s should know how to work together and have all the fancy string
behavior.
The closest approximation today is boost::array<char, 10>
Use e.g.
std::tr1::array<char, 10>
I've been using something like this for strings allocated on stack or as a part of another object. Which in release becomes a char*
#ifdef DEBUG
#define STR_DEBUG
#endif
#define FIXED_STRING( maxSize ) ReservedString<maxSize> _Tmp##__LINE__;
class FixedString{
public:
FixedString& operator =( char const * const pStr );
//FixedString& operator =( FixedString const &pStr );
operator const char*() const { return mStr; }
const char* cStr() const { return mStr; }
FixedString& operator +=(const char *pStr);
bool equals( const char *pStr );
bool beginsWith( const char *pStr );
/// rises ASSERT if not enough
void ensureEnoughForNMore( int NMoreSymbols );
protected:
char *mStr;
#ifdef STR_DEBUG
ui16 mMaxLength;
#endif
private:
#ifdef STR_DEBUG
FixedString( char *str, ui16 maxLength ): mStr(str), mMaxLength(maxLength) {}
#else
FixedString( char *str ): mStr(str) {}
#endif
template<int>
friend class ReservedString;
};
template <int MAX_LENGTH> class ReservedString{
public:
operator FixedString() {
#ifdef STR_DEBUG
return FixedString( mBuf, MAX_LENGTH );
#else
return FixedString( mBuf );
#endif
}
private:
char mBuf[MAX_LENGTH+1];
};
How about inheriting std::string
privately then exposing a smaller interface with using
, and writing your own << and >> functions?
With ISO C++ +17 you can do this
#include <string_view>
......
char dataBuffer[BUFF_SIZE];
auto commandString = std::string_view{ dataBuffer };
......
Why not use std::basic_string from STL as a fixed string class?
You can use the constructor
basic_string(
size_type _Count,
value_type _Ch,
const allocator_type& _Al = Allocator ( )
);
as initializer.
Later edit: Example:
std::string my10CharStringInitializedWithSpace( 10, ' ');
With C++11, one can go for
std::array<char,10> s;
Also std::string equivalent can always be constructed, when required
std::string s2(std::begin(s), std::end(s));
There's probably something in boost that provides this (the closest I've personally seen is Boost.Array, which is insufficient). However, if you're just looking to model the "important subset" of std::string
, it's not very difficult to make a fixed-length equivalent:
template <size_t N>
class fixed_string
{
// ... interface looks like std::string
};
For anyone asking about why bothering to do this at all, the main benefit is to avoid memory allocation without losing most of the useful std::string
API. If there's another way to do this with std::allocator
, I'd be curious to know.
I needed something like this as well. I built a solution based on istream_iterator with an added constraint on block_size.
You can find my repository block_iterator on GitHub
It is only a single header here
This works like istream_iterator so you split a string into 3 character strings as follows:
constexpr auto N = 3;
const auto example = "AAABBBCCC";
std::istringstream ss(example);
std::vector<std::string> blocks{};
std::copy(istream_block_iterator<std::string>(ss, N), istream_block_iterator<std::string>(),std::back_inserter(blocks));
C style character array?
char label[10] = "a string";
If I understand you correctly, you don't want to use std::string
because you're worried it might silently expand on you. I see a couple of options:
Use a raw C-style string and the functions from
cstdio
that take a length argument (e.g.,fgets
).Use a
std::vector<char>
.
精彩评论