我有char *,它具有固定(已知)宽度,但不会以空值终止。
我想将它传递给LOG4CPLUS_ERROR("Bad string " << char_pointer);
,但由于它不是空终止,它会打印出来。
在不执行复制的情况下获得"(char[length])*char_pointer"
的轻量级方法的任何建议?
答案 0 :(得分:7)
不,你必须进行深层复制并将其终止。该代码需要以空字符结尾的字符串,它表示以空终止符结尾的连续字符块。
答案 1 :(得分:5)
如果你的目标是打印这样一个字符串,你可以:
将所有这些包裹在一个函数中。
答案 2 :(得分:2)
我们对char*
和char[]
之间转换的语义感到困惑。退后一步,你想做什么?如果这是一个错误条件的简单情况,将结构的内容流式传输到流,为什么不正确地执行?
e.g。
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
的实例,而不必担心空终止字符串等。!
答案 3 :(得分:2)
iostream
s 当你写一个真实的iostream时,你可以使用ostream.write()
,它需要char*
和一个大小来写入多少字节 - 不需要空终止。 (实际上,字符串中的任何空字符都将写入ostream,并且不会用于确定大小。)
在某些日志记录库中,您写入的流不是真正的iostream。 Log4CPP就是这种情况。
但是,在Log4CPlus这就是亚特正在使用的内容中,您要写的对象是std::basic_ostringstream<tchar>
(请参阅loggingmacros.h
和streams.h
定义,因为文档中没有一个是明显的)。只有一个问题:在宏LOG4CPLUS_ERROR
中,第一个<<
已内置到宏中,因此他无法调用LOG4CPLUS_ERROR(.write(char_pointer,length))
或类似的内容。不幸的是,在没有解构LOG4CPLUS_ERROR
错误宏并进入Log4CPlus内部
我不确定你为什么要避免在此时复制字符串,因为你可以看到日志库里面有很多复制。任何避免额外字符串副本的尝试都可能是无根据的优化。
我将假设它是代码清洁的问题,也许是确保副本发生在LOG4CPLUS_ERROR
宏内部而不是外部的问题。在这种情况下,只需使用:
LOG4CPLUS_ERROR("Bad string " << std::string(char_pointer, length));
答案 4 :(得分:1)
我在我的工具包中保留了一个字符串引用类,仅用于这些类型的情况。这是该类的大大缩写版本。我删除了与此特定问题无关的任何内容:
#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对象的整个生命周期内都有效。这样,您可以以最小的开销传递并处理字符串信息。
答案 5 :(得分:0)
当你知道它是固定长度时:为什么不简单地再添加一个charakter到数组的大小?然后你可以用\ 0终止字符轻松地填充这个最后一个字符,一切都很好
答案 6 :(得分:0)
不,你必须复制它。语言中没有适当的转换可用于从中获取数组类型。
你想要做到这一点似乎很奇怪,或者你首先有一个没有终止的C风格的字符串。
为什么不使用std::string
?