2014-02-12 68 views
1

我试图实现与C#String.FormatC++相同的功能。不过,我有在某些情况下,输出一个问题:C++ String.Format实现错误

#include <iostream> 
#include <string> 

class format_base 
{ 
public: 
    format_base(const char *base) : argp_(0) 
    { 
     base_ = (char*)calloc(4097, sizeof(char)); 
     sz_ = 4097; 
     memcpy(base_, base, strlen(base)); 
    }; 
    ~format_base() 
    { 
     free(base_); 
    } 
    format_base &arg(const char *argument) 
    { 
     if ((strlen(base_) - 3) + strlen(argument) > sz_) 
     { 
      base_ = (char*)realloc(base_, (sz_ *= 2)); 
     } 
     std::string elim = "{"; 
     elim.append(std::to_string(argp_++)); 
     elim.append("}"); 
     std::string tbase = base_; 
     size_t f = tbase.find(elim.c_str()); 
     if (f != std::string::npos) 
     { 
      tbase.replace(f, elim.size(), argument); 
     } 
     memcpy(base_, tbase.c_str(), tbase.length()); 
     return *this; 
    } 
    char *value() 
    { 
     return base_; 
    } 
    char *operator()() 
    { 
     return base_; 
    } 
private: 
    char *base_; 
    size_t argp_, sz_; 
}; 

format_base &format(const char *base) 
{ 
    return *new format_base(base); 
} 

int main() 
{ 
    std::cout << format("Hello {0}").arg("a")(); // Prints "Hello a0} " 
    std::cout << format(" Hello {0}").arg("ab")(); // Prints " Hello ab} " 
    std::cout << format(" Hello {0}\n").arg("abc")(); // Prints " Hello abc\n" 
    std::cout << format("Hello {0}\n").arg("a")(); // Prints "Hello a\n}" 
    std::cout << format("Hello {0}\n").arg("ab")(); // Prints "Hello ab\n" 
    std::cout << format("Hello {0}\n").arg("abc")(); // Prints "Hello abc\n" 
    getchar(); 
} 

总功率:

你好A0}你好AB}您好ABC

你好一个

}

您好ab

_

你好ABC

_

我很困惑,我将不胜感激,如果你能帮助

+2

已经有一个'std :: to_string'函数返回一个合适的'std :: string'。不需要使另一个返回C字符串。 – chris

+3

你确定你不想在任何地方使用std :: string而不是手动管理内存吗? –

+0

@SebastianRedl - 我喜欢这样:) – Joseph

回答

1

我想你忘了正确设置字符串长度。 “坏”输出只是结果字符串和旧字符串的最后一个字符。如果由于替换而缩短了字符串,则需要切断字符串。

memcpy(base_, tbase.c_str(), tbase.length()); 

length()不计终止\0,所以你可能想

strcpy(base_, tbase.c_str()); 

memcpy(base_, tbase.c_str(), tbase.length()+1); 
1

,就应该替换:

memcpy(base_, tbase.c_str(), tbase.length()); 

有:

strcpy(base_, tbase.c_str()); 

你在哪里计划从这个分配中释放内存? :

return *new format_base(base); 
char *s = (char*)calloc(2, sizeof(char));