c++, truncate a char array
I'm working on a project where I have a Time class and I need to format the time.
void Time::FormatTime(char *string, unsigned int max_string_len) {
ostrstream fd;
ft << hour << ":" << minutes;
cout << ft.str() << endl;
}
The user passes in a pointer to their string and the max length of the string and I need to check that the time string 开发者_运维知识库isn't longer than max_string_len and if it is, then truncate it. I'm not sure how to do the truncation as it's been awhile since I've written any C++.
I'd like to not use the STL if possible.
Thanks
Always use strncpy()
to safely truncate a string into a char[N]
.
void Time::FormatTime(char *str, unsigned int max_string_len) {
if ( max_string_len == 0 ) return;
ostringstream ft; // strstream is obsolete, use stringstream
ft << hour << ":" << minutes;
strncpy( str, ft.str().c_str(), max_string_len );
str[ max_string_len - 1 ] = 0;
}
if( str.length() > max_string_len )
{
str = str.substr( 0, max_string_len );
}
strncpy( string, str.c_str(), max_string_len );
This does what you want:
void Time::FormatTime(char *string, unsigned int max_string_len) {
ostrstream fd;
ft << hour << ":" << minutes;
std::string str = ft.str();
str.resize(max_string_len);
strcpy(string, str.c_str());
}
EDIT: I've updated my code thanks to the helpful feedback of potatoswatter and quanmrana.
If the first parameter can be modified then you can just place a 0 in the correct position to be a string terminator, however this is a fairly nasty (but fast) solution. Otherwise, you'll want to create a new array of characters and only copy over the correct number of characters, remembering to allocate an extra character for the zero terminator.
I'm half guessing at what you want, but I think it's something like the following, where I'm assuming or changing:
ft
really should befd
- I used an
ostringstream
object instead of anostrstream
max_string_len
is the size of the destination buffer in characters (including the character that will hold the '\0' terminator)- you're not really interested in the formatted string being sent to
std::cout
, but want it in the caller's provided buffer - I changed the name of parameter
string
tos
so it wouldn't be confused with thestd:string
type.
The code:
void Time::FormatTime(char *s, unsigned int max_string_len) {
if (max_string_len == 0) {
return; // no buffer, bail out
}
std::ostringstream fd;
fd << hour << ":" << minutes;
size_t len = fd.str().copy( s, max_string_len - 1); // leave room for the null terminator
s[len] = '\0';
}
If you really don't want any part of the STL, then the following C-styled code should do the trick:
void Time::FormatTime(char *s, unsigned int max_string_len) {
snprintf( s, max_string_len, "%02u:%02u", hour, minutes);
}
It's simpler, but may C++ developers don't like using the printf()
family because it's not typesafe.
From your requirements, you seem intent on writing C instead of C++, but I guess that's your business. For your specification, however, it appears that the right answer is strftime()
.
精彩评论