将Char *转换为Char[]

char* to char[]

本文关键字:Char 转换      更新时间:2023-10-16

我有一个char*,它是固定的(已知的)宽度,但不是null终止。

我想把它传递给LOG4CPLUS_ERROR("Bad string " << char_pointer);,但由于它不是null终止的,它将打印全部

有没有建议一些轻量级的方法来获得"(char[length])*char_pointer"而不执行复制?

不行,你必须深度复制并以空终止。该代码需要一个以空结束的字符串,它意味着以空结束符结束的连续字符块。

如果您的目标是打印这样一个字符串,您可以:

  1. 存储最后一个字节
  2. 用代替
  3. 打印字符串
  4. 打印存储的字节。
  5. 将存储的字节放回字符串的最后一个位置。

Real iostream s

当你写一个真正的iostream,那么你可以只使用ostream.write(),它需要一个char*和一个大小多少字节写入-没有null终止必要。(实际上,字符串中的任何空字符都将被写入ostream,而不会用于确定大小。)

<标题> 日志库

在一些日志库中,你写入的流不是一个真正的iostream。Log4CPP就是这种情况。

然而,在Log4CPlus中,这是matt正在使用的,您正在编写的对象是std::basic_ostringstream<tchar>(参见loggingmacros.hstreams.h的定义,因为这从文档中都不明显)。只有一个问题:在宏LOG4CPLUS_ERROR中,第一个<<已经内建到宏中,因此他将无法调用LOG4CPLUS_ERROR(.write(char_pointer,length))或类似的东西。不幸的是,如果不解构LOG4CPLUS_ERROR错误宏并进入Log4CPlus的内部,我看不到一个简单的方法来解决这个问题。<标题> 解决方案

我不知道你为什么要避免复制这个字符串,因为你可以看到在日志库中有很多复制。任何避免额外字符串复制的尝试都可能是不必要的优化。

我假设这是一个代码清洁度的问题,也许是一个确保复制发生在LOG4CPLUS_ERROR宏内部的问题,而不是在它外面。在这种情况下,只需使用:

LOG4CPLUS_ERROR("Bad string " << std::string(char_pointer, length));

我们正在讨论char*char[]之间转换的语义。退后一步,你到底想干什么?如果这是一个简单的错误情况,将结构的内容输出到流,为什么不正确地做呢?

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

现在您可以简单地输出foo实例,而不必担心null终止字符串等!

我在工具包中保留了一个字符串引用类,专门用于这些类型的情况。这是这门课的一个大大简化的版本。我删除了与这个特定问题无关的任何内容:

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

或者

LOG4CPLUS_ERROR("Bad string " << stringref(char_pointer, length));

字符串引用类的思想是保留足够的关于字符串的信息(大小和指针),以引用任何表示字符串的内存块。它依赖于您来确保底层字符串数据在stringref对象的整个生命周期中有效。通过这种方式,您可以以最小的开销传递和处理字符串信息。

当您知道它是固定长度时:为什么不简单地在数组的大小上再增加一个字符呢?然后可以很容易地用结束字符填充最后一个字符,这样就可以了

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

你想这样做似乎很奇怪,或者你一开始就有一个不终止的c风格字符串。

为什么不使用std::string ?