Скопируйте строку в массив символов - PullRequest
0 голосов
/ 02 марта 2012

Я пытаюсь скопировать строку, которая может содержать нулевые символы в середине, в массив символов.Я построил следующую функцию.

 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

Мой вопрос заключается в том, что этот метод гарантирует, что я не потеряю символы после нулевого элемента.и другой мой вопрос, я получаю эту ошибку компоновщика, которую я не знаю, что это значит.

/ tmp / ccUpCRaz.o: В функции `Parser :: RuleParser (char const *) ':Parser.cpp :(. Text + 0x3f6): неопределенная ссылка на Parser :: SaveStringToChar (std :: basic_string, std :: allocator> &, char const * &) 'collect2: ld вернул 1 состояние выхода

anyhint, пожалуйста.

это функция, которую я передаю для сравнения.

  void Search( size_t TextLength, const char *Text, const vector<const char *> &patterns );

Ответы [ 4 ]

2 голосов
/ 02 марта 2012

Вам необходимо определить функцию как член 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 в функцию сравнения и сравните с элементами vector<std::string>: std::string::operator==() будет правильно сравнивать строки будут встроены нулевые символы. Затем вы можете использовать std::find() для поиска vector<std::string> для std::string чтения из файла.

1 голос
/ 02 марта 2012

Ваша строковая копия выглядит нормально, но если вы делаете это для передачи символа * функции, есть лучшие способы увидеть:

std::string str;
//...
my_func(str.c_str());

hmjd содержит ошибку вашей ссылки.

0 голосов
/ 02 марта 2012

мой вопрос: этот метод гарантирует, что я не потеряю символы после нулевого элемента

Вся строка будет скопирована в буфер, даже если она содержит нулевые символы. std::copy не интерпретирует данные, которые он копирует, он просто копирует количество элементов, которые вы ему сообщаете.

Однако, если строка содержит нулевые символы, вы не можете использовать ее с любой функцией, которая работает со строками с нулевым символом в конце (например, в <cstring>); они будут интерпретировать первый нулевой символ как конец строки.

Кроме того, по крайней мере в опубликованном вами коде вы возвращаете указатель как const char *, подразумевая, что вы не будете изменять копию. В этом случае вам действительно нужна копия данных строки, или этого достаточно, чтобы вместо нее вернуть str.c_str()?

мой другой вопрос: я получаю эту ошибку компоновщика

Похоже, вам не хватает определения Parser::SaveStringToChar. Я предполагаю, что код, который вы разместили, взят из исходного файла, а не функции, определенной внутри класса Parser. Если это так, то вы забыли указать, что это функция-член, и вместо этого определили не-член; измените его на

void Parser::SaveStringToChar(string &mystring,const char * &ArrChar)
     ^^^^^^^^
0 голосов
/ 02 марта 2012

См. Ответ hmjd об ошибке ссылки.

Что касается скопированных символов, вы на самом деле не потеряете никаких символов, поскольку все они безопасно скопированы в выходной буфер.Однако, если в середине строки действительно есть \0 символов, ни одна из строковых функций в стиле C (например, printf) не будет корректно работать с ней.
И вызывающая подпрограмма не будет знать, какой длиныстроки, и, следовательно, каков вновь выделенный размер буфера.Вы также должны вернуть длину строки (либо в качестве возвращаемого значения, либо в другом ссылочном аргументе).

...