Преобразовать строку в массив символов без пробелов в C ++ - PullRequest
2 голосов
/ 10 ноября 2011

В моем коде у меня есть массив символов, и вот он: char pIPAddress[20]; И я устанавливаю этот массив из строки с этим кодом: strcpy(pIPAddress,pString.c_str());

после этой загрузки; например, значение pIPAddress - "192.168.1.123". Но я не хочу пробелов. Мне нужно удалить пробелы. Для этого я сделал это pIPAddress[13]=0;.

Но если длина IP-адреса высока, это не сработает. Как я могу рассчитать эффективный путь? или другие способы?

Thnx

Ответы [ 5 ]

5 голосов
/ 10 ноября 2011

Самый простой подход, который вы можете сделать, - это использовать алгоритм std::remove_copy:

std::string ip = read_ip_address();
char ipchr[20];
*std::remove_copy( ip.begin(), ip.end(), ipchr, ' ' ) = 0; // [1]

Следующий вопрос - зачем вам это делать, потому что лучше не копировать его?в массив, но вместо этого удалите пробелы из строки и затем используйте c_str() для получения указателя ...

РЕДАКТИРОВАТЬ Согласно предложению Джеймса, если вы хотите удалить все пробелы ине только символ ' ', вы можете использовать std::remove_copy_if с функтором.Я протестировал передачу std::isspace из заголовка <locale> напрямую, и, похоже, это работает, но я не уверен, что это не будет проблематично с не-ascii символами (которые могут быть отрицательными):

#include <locale>
#include <algorithm>
int main() {
   std::string s = get_ip_address();
   char ip[20];
   *std::remove_copy_if( s.begin(), s.end(), ip, (int (*)(int))std::isspace ) = 0; // [1]
}

ужасный приведение в последнем аргументе требуется для выбора конкретной перегрузки isspace.

[1] Необходимо добавить *... = 0;для обеспечения NUL окончания строки.Алгоритмы remove_copy и remove_copy_if возвращают итератор end в выходной последовательности (т. Е. Один после последнего отредактированного элемента), и *...=0 разыменовывает этот итератор для записи NUL.В качестве альтернативы, массив может быть инициализирован перед вызовом алгоритма char ip[20] = {};, но он будет записывать \0 во все 20 символов в массиве, а не только в конец строки.

0 голосов
/ 10 ноября 2011

Если пробелы находятся только в конце (или начале) вашей строки, вам лучше всего использовать boost :: trim

#include <boost/algorithm/string/trim.hpp>

std::string pString = ...
boost::trim(pString);
strcpy(pIPAddress,pString.c_str());

Если вы хотите ввести код вручную, <cctype> имеет функцию isspace , которая также имеет версию, специфичную для локали .

0 голосов
/ 10 ноября 2011

Я думаю, что если вы используете

зЬгср (pIPAddress, pString.c_str ())

тогда ничего не нужно делать, так как c_str () возвращает символ * в строку с нулевым символом в конце. Таким образом, после выполнения вышеуказанной операции ваш массив символов 'pIPAddress' сам по себе завершается нулем. Поэтому ничего не нужно делать, чтобы отрегулировать длину, как вы сказали.

0 голосов
/ 10 ноября 2011

Я вижу, у вас есть std::string.Вы можете использовать метод erase():

std::string tmp = pString;
for(std::string::iterator iter = tmp.begin(); iter != tmp.end(); ++iter)
  while(iter != tmp.end() && *iter == ' ') iter = tmp.erase(iter);

Затем вы можете скопировать содержимое tmp в ваш массив символов.Обратите внимание, что массивы char полностью устарели в C ++, и вы не должны использовать их, если в этом нет необходимости.В любом случае, вы должны выполнять все ваши манипуляции со строками, используя std::string.

0 голосов
/ 10 ноября 2011

Чтобы решение работало во всех случаях, я предлагаю вам выполнить итерацию по вашей строке, и при поиске пробела вы с ней справляетесь.

Возможно, вам понадобится более высокоуровневое решение для использования строкиметоды, которые позволяют вам сделать это автоматически.(см .: http://www.cplusplus.com/reference/string/string/)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...