C++ 字符*到字符[]

C++ 字符*到字符[],c++,C++,我有固定(已知)宽度但不是以null结尾的字符* 我想把它传递到LOG4CPLUS\u错误(“坏字符串”不,您必须进行深度复制并以null结尾。该代码需要以null结尾的字符串,它意味着一个以null结尾的连续字符块。当您知道它是固定长度的时:为什么不简单地在数组的大小上再添加一个字符?然后您可以轻松地用\0终止字符填充最后一个字符如果您的目标是打印这样一个字符串,那么您可以: 存储最后一个字节 将其替换为\0 打印字符串 打印存储的字节 将存储的字节放回字符串的最后一个位置 将所有这些都包装到

我有固定(已知)宽度但不是以null结尾的字符*


我想把它传递到
LOG4CPLUS\u错误(“坏字符串”不,您必须进行深度复制并以null结尾。该代码需要以null结尾的字符串,它意味着一个以null结尾的连续字符块。

当您知道它是固定长度的时:为什么不简单地在数组的大小上再添加一个字符?然后您可以轻松地用\0终止字符填充最后一个字符如果您的目标是打印这样一个字符串,那么您可以:

  • 存储最后一个字节
  • 将其替换为\0
  • 打印字符串
  • 打印存储的字节
  • 将存储的字节放回字符串的最后一个位置

  • 将所有这些都包装到一个函数中。

    不,您必须复制它。在语言中没有适当的转换,您可以使用它来获取数组类型

    这看起来很奇怪,你想这样做,或者你有一个非终止的C风格的字符串放在首位


    为什么不使用
    std::string

    我在工具箱中保留了一个字符串引用类,仅用于此类情况。下面是该类的一个非常简短的版本。我删除了与此特定问题无关的任何内容:

    #include <iostream>
    
    class stringref {
    public:
        stringref(const char* ptr, unsigned len) : ptr(ptr), len(len) {}
    
        unsigned length() { return len; }
        const char* data() { return ptr; }
    
    private:
        const char* ptr;
        unsigned len;
    };
    
    std::ostream& operator<< (std::ostream& os, stringref sr) {
        const char* data = sr.data();
        for (unsigned len = sr.length(); len--; )
            os << *data++;
        return os;
    }
    
    using namespace std;
    
    int main (int argc, const char * argv[])
    {
        cout << "string: " << stringref("test", 4) << endl;
    }
    
    #包括
    stringref类{
    公众:
    stringref(const char*ptr,unsigned len):ptr(ptr),len(len){
    无符号长度(){return len;}
    const char*data(){return ptr;}
    私人:
    常量字符*ptr;
    无符号len;
    };
    
    std::ostream&operator我们对
    char*
    char[]
    之间的转换语义感到困惑。退一步,你想做什么?如果这是一个简单的错误情况,将结构的内容流式输出到流,为什么不正确执行呢

    e、 g

    structfoo
    {
    char a1[10];
    chara2[10];
    chara3[10];
    字符a4[10];
    };
    //自由函数以正确地流式传输上述结构。。
    std::ostream operatorReal
    iostream
    s 当您在写入真正的iostream时,您可以只使用
    ostream.write()
    ,它需要
    char*
    和写入多少字节的大小——不需要空终止符(事实上,字符串中的任何空字符都会写入ostream,而不会用于确定大小)

    日志库 在某些日志库中,您写入的流不是真正的iostream



    但是,在matt使用的对象中,您正在写入的对象是一个
    std::basic_ostringstream
    (请参见
    loggingmacros.h
    streams.h
    ,以了解定义,因为从文档中看不出这一切)。只有一个问题:在宏
    LOG4CPLUS\u ERROR
    中,第一个
    所有字符串都必须以null结尾。没有转换会有帮助。您需要手动添加
    '\0'
    字符。@Let\u Me\u be:这不是真的,是吗。真正的问题是没有从指针到数组的有效转换。@Tomalak With
    sizeof()
    数组和指针的例外实际上是无法区分的。@Tomalak(a)问题中没有涉及转换。(b)当然它们不兼容,这就像说
    int x[];
    float x[];
    是兼容的。但是
    float**x;
    float*x[]是兼容的
    float x[a][b];
    float(*x)[a]兼容;
    (c)数组可隐式转换为指向第一个元素的指针,这不仅适用于函数调用。在日志库中似乎不是这样,有时是实现流的库(如iostreams库)实现一个
    write(char*,streamsize)
    函数,该函数可以轻松处理这种情况。他如何在没有副本的情况下做到这一点?分配内存时只需使用(knownsize)+1,在数组中填充数据后只需执行数据[knownsize]='\0';如果他能做到这一点,他首先就可以让他的C字符串正常工作。这个问题是关于如何解决这种能力不足的问题。也许他不知道这样可以简单地添加终止字符;)无论如何,当他说数据的大小是已知的时,我看不出他不能再分配一个字符的任何原因。已知与可变不同……即使可以,也不支持(AFAIK)直接流式输出数组(不使用
    std::copy
    )。最好的方法是构造一个
    std::string()
    ,使用一个变量,该变量接受一个
    const char*
    和一个
    size\u t
    ,并在一个充满char[]s的结构中将char*转换为char[]。完整结构作为一条记录甚至一个字符[]工作。不适合我的职位,但很有用elsewhere@matt:好的。答案是正确的复制它,最理想的方法是用Nim提到的细节构造一个
    std::string
    ,最简单的方法是用
    const char*
    size\u t
    构造一个
    std::string
    ,除非你可以访问底层的流对象。是的,我想甚至连char[]将需要以null结尾。@matt:那样,或者您需要能够将长度传递给正在调用的任何函数。matt没有iostreams的优势,但您有。为什么不直接使用
    ostream.write(char*,streamsize)
    ?我没有使用log4c++,但示例的语法使我相信它在内部使用iostreams。LOG4CPLUS_错误(“坏字符串”@Ferruccio:Log4cpp没有——它重载了
    运算符。对log4c++源代码的快速搜索表明它在内部使用stringstreams缓冲输出。因此可以使用iostreams。但是,仍然不能使用ostream::write()因为您没有对stringstream对象的直接访问权限。宏依赖于您使用OperatorID
    
    LOG4CPLUS_ERROR("Bad string " << stringref(char_pointer, length));
    
    struct foo
    {
      char a1[10];
      char a2[10];
      char a3[10];
      char a4[10];
    };
    
    // free function to stream the above structure properly..
    std::ostream operator<<(std::ostream& str, foo const& st)
    {
      str << "foo::a1[";
      std::copy(st.a1, st.a1 + sizeof(st.a1), std::ostream_iterator<char>(str));
      str << "]\n";
    
      str << "foo::a2[";
      std::copy(st.a2, st.a2 + sizeof(st.a2), std::ostream_iterator<char>(str));
      str << "]\n";
    
      :
    
      return str;
    }
    
    LOG4CPLUS_ERROR("Bad string " << std::string(char_pointer, length));