我正在尝试将中间可能包含空字符的字符串复制到char数组中。 我构建了以下函数。
void SaveStringToChar(string &mystring,const char * &ArrChar)
{//begin function
std::string str;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0';
ArrChar = writable;
}//end function
我的问题是这个方法保证我不会丢失null元素后的字符。 而我的另一个问题是我收到此链接器错误,我不知道这意味着什么。
/tmp/ccUpCRaz.o:在函数`Parser :: RuleParser(char const *)'中: Parser.cpp :(。text + 0x3f6):未定义的引用Parser :: SaveStringToChar(std :: basic_string,std :: allocator>&,char const *&)' collect2:ld返回1退出状态
任何请点。
这是我传递比较的功能。
void Search( size_t TextLength, const char *Text, const vector<const char *> &patterns );
答案 0 :(得分:2)
您需要将该函数定义为Parser::
的成员。它目前定义为:
void SaveStringToChar(string &mystring,const char * &ArrChar)
更改为:
void Parser::SaveStringToChar(string &mystring,const char * &ArrChar)
std::copy()
将复制所有字符。但是,调用者不会知道ArrChar
实际指向的字符数,因为strlen()
之类的函数将在第一个空字符处停止计数。您可以更改SaveStringToChar()
的签名以接受另一个参数size_t& ArrCharLen
,该参数将填充ArrChar
中的字符数。当然,mystring
的长度为ArrChar
,因此您可能在调用SaveStringToChar()
之前已将其存储起来。
编辑(vector<const char*>
评论后):
const char*
添加到vector
后,真正的字节数会丢失。为什么不使用vector<std::string>
并std::string::length()
知道std::string
中实际存储的字符数。
EDIT2(比较函数.c_str()与text.length()之后:
而不是传递.c_str()
和.length()
来与vector<const char*>
中的元素进行比较,只需将std::string
传递给compare函数,然后与{{1}的元素进行比较}:vector<std::string>
将正确比较字符串将嵌入的空字符。然后,您可以使用std::string::operator==()
在std::find()
中搜索从文件中读取的vector<std::string>
。
答案 1 :(得分:1)
你的字符串副本似乎很好,但是如果你这样做是为了将char *传递给一个函数,那么有更好的方法可以看到:
std::string str;
//...
my_func(str.c_str());
hmjd有你的链接错误。
答案 2 :(得分:0)
请参阅hmjd的链接错误答案。
对于复制的字符,您实际上不会丢失任何字符,因为它们都被安全地复制到输出缓冲区。但是,如果字符串中间确实有\0
个字符,则没有任何C样式的字符串函数(如printf)可以正常工作。
而且调用例程也不会知道字符串的长度是多少,因此新分配的缓冲区大小是多少。您也应该返回字符串长度(作为返回值,或者在另一个引用参数中)。
答案 3 :(得分:0)
我的问题是这个方法保证我不会丢失空元素后的字符
整个字符串将被复制到缓冲区中,即使它确实包含空字符。 std::copy
不会以任何方式解释它复制的数据,它只会复制您告诉它的元素数量。
但是,如果字符串确实包含空字符,那么不能将它与任何使用以null结尾的字符串(例如<cstring>
中的字符串)的函数一起使用;他们会将第一个空字符解释为字符串的结尾。
此外,至少在您发布的代码中,您将指针返回为const char *
,这意味着您不会修改副本。在这种情况下,你真的需要一个字符串数据的副本,还是足以返回str.c_str()
?
我的另一个问题是我收到此链接器错误
看起来你错过了Parser::SaveStringToChar
的定义。我猜你发布的代码来自源文件,而不是Parser
类内联定义的函数。如果是这种情况,那么你忘了指定它是一个成员函数,而是定义了一个非成员;将其更改为
void Parser::SaveStringToChar(string &mystring,const char * &ArrChar)
^^^^^^^^