繁体   English   中英

char * to char []

[英]char* to char[]

我有char *,它具有固定(已知)宽度但不是空终止。

我想把它传递给LOG4CPLUS_ERROR("Bad string " << char_pointer); 但由于它的非null终止,它将打印出所有内容。

任何轻量级的方法得到"(char[length])*char_pointer"没有执行副本的任何建议?

不,你必须进行深度复制并将其终止。 该代码需要一个以null结尾的字符串,它表示以null终止符结尾的连续字符块。

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

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

将所有这些包裹在一个函数中。

我们开始讨论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实例,而不必担心空终止字符串等!

真实的iostream

当你写一个真正的iostream时,你可以使用ostream.write() ,它接受一个char*和一个大小来写入多少字节 - 不需要空终止。 (实际上,字符串中的任何空字符都将写入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));

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

#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对象的整个生命周期内都有效。 这样,您可以以最小的开销传递并处理字符串信息。

当你知道它是固定长度的时候:为什么不简单地再添加一个charakter到数组的大小? 然后你可以用\\ 0终止字符轻松填充最后一个字符,一切都会好的

不,你必须复制它。 您可以使用语言中的正确转换来获取数组类型。

你想要做到这一点似乎很奇怪,或者你首先有一个非终止的C风格的字符串。

你为什么不使用std::string

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM