开发者

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 be fd
  • I used an ostringstream object instead of an ostrstream
  • 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 to s so it wouldn't be confused with the std: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().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜