C++ c++;,截断字符数组

C++ c++;,截断字符数组,c++,C++,我正在做一个项目,我有一个时间班,我需要格式化时间 void Time::FormatTime(char *string, unsigned int max_string_len) { ostrstream fd; ft << hour << ":" << minutes; cout << ft.str() << endl; } void Time::FormatTime(char*string,uns

我正在做一个项目,我有一个时间班,我需要格式化时间

void Time::FormatTime(char *string, unsigned int max_string_len) {
    ostrstream fd;
    ft << hour << ":" << minutes;
    cout << ft.str() << endl;    
}
void Time::FormatTime(char*string,unsigned int max\u string\u len){
奥斯特流fd;

ft如果第一个参数可以修改,那么您可以在正确的位置放置一个0作为字符串终止符,但是这是一个相当讨厌的(但是很快的)解决方案。否则,您需要创建一个新的字符数组,并且只复制正确数量的字符,记住为零终止符分配一个额外的字符。

这就是您想要的:

 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());
 }
void Time::FormatTime(char*string,unsigned int max\u string\u len){
奥斯特流fd;

FTP

从您的要求来看,您似乎有意编写C++而不是C++,但我想这是您的业务。但是,对于您的规范,似乎正确的答案是“代码> STFFTIME())/>代码>

< P>我对您想要的东西半猜测,但我认为这是如下的,我假设或改变:

  • ft
    真的应该是
    fd
  • 我使用了
    ostringstream
    对象,而不是
    ostringstream
  • max\u string\u len
    是目标缓冲区的大小(以字符为单位)(包括将容纳'\0'终止符的字符)
  • 您对发送到
    std::cout
    的格式化字符串并不感兴趣,而是希望它位于调用方提供的缓冲区中
  • 我将参数
    string
    的名称更改为
    s
    ,这样就不会与
    std:string
    类型混淆
守则:

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';
}

比较简单,但可能C++开发人员不喜欢使用<代码> Prtff()/Cuth>家族,因为它不是类型化的。

< P>总是使用<代码> STRCNCY()/Cyto>将字符串安全地截断为<代码> char [n] < /Cord>
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;
}
void Time::FormatTime(char*str,unsigned int max\u string\u len){
if(max_string_len==0)返回;
ostringstream ft;//stream已过时,请使用stringstream

ft这是最简单的方法。简短而简单。-1:如果max_string_len为0,则strlen(string)可能未定义。
str.resize(n)
调整
str
使
n
字符不包括终止字节。
strcpy
复制
n
字符和终止字节,这会导致溢出。@Manuel:现在使用stl,还应该将
string
中的第一个参数重命名为类似
str
。你不想把任何东西与
std::string
混淆。Crud-我只是注意到不想使用STL的愿望-我在这里使用STL,因为问题中给出的示例使用了它,标签上写着“C++”…如果我应该删除此答案,请发表评论,如果您想要纯C函数,让我们将此问题重新标记为C问题。我喜欢您的第一个小片段,但我不断遇到以下错误:“left of'.copy'必须具有class/struct/union”在VS2008上添加了
#include
hour
minutes
声明,并更正了
max\u string\u len
之后,第一个代码段编译得很好。我应该明确指出,
std::ostringstream
需要一个
#include
,并且我假设
hour
minutes
Time
类的成员(基于原始代码片段)-1:你需要将
max\u string\u len-1
传递给
snprintf
,那代码就溢出了。如果你或多或少知道时间需要5个字符,为什么不断言长度足够了呢?被截断的时间表示法对你有什么好处?显然,要练习避免字符串溢出…@Manuel:好吧,尽管我认为不够这太傻了。请注意,
snprintf
的limit参数中不包含终止字节,因此将0传递给此函数就像将-1传递给
snprintf
。哎呀,请不要再提
snprintf
void Time::FormatTime(char *s, unsigned int max_string_len) {

    snprintf( s, max_string_len, "%02u:%02u", hour, minutes);
}
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;
}