将字符串复制到char数组

时间:2012-03-02 12:14:57

标签: c++ string char type-conversion

我正在尝试将中间可能包含空字符的字符串复制到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 );

4 个答案:

答案 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)
     ^^^^^^^^