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