Разделить строку на отдельные пробелы
Возможный дубликат:
Как разбить строку на С++?
Мне нужно разбить строку на отдельные пробелы и сохранить ее в массив строк. Я могу достичь этого, используя istringstream, но то, чего я не могу достичь, следующее:
Я хочу, чтобы каждое пространство прерывало текущее слово. Итак, если есть два пробела подряд, один элемент моего массива должен быть пустым.
Например:
(подчеркивание обозначает пробел)
This_is_a_string.
gets split into:
A[0] = This
A[1] = is
A[2] = a
A[3] = string.
This__is_a_string.
gets split into:
A[0] = This
A[1] = ""
A[2] = is
A[3] = a
A[4] = string.
Как это реализовать?
Ответы
Ответ 1
Вы даже можете развить свою собственную функцию разделения (я знаю, немного старомодный):
unsigned int split(const std::string &txt, std::vector<std::string> &strs, char ch)
{
unsigned int pos = txt.find( ch );
unsigned int initialPos = 0;
strs.clear();
// Decompose statement
while( pos != std::string::npos ) {
strs.push_back( txt.substr( initialPos, pos - initialPos + 1 ) );
initialPos = pos + 1;
pos = txt.find( ch, initialPos );
}
// Add the last one
strs.push_back( txt.substr( initialPos, std::min( pos, txt.size() ) - initialPos + 1 ) );
return strs.size();
}
Затем вам просто нужно вызвать его с помощью вектора <string> в качестве аргумента:
int main()
{
std::vector<std::string> v;
split( "This is a test", v, ' ' );
show( v );
return 0;
}
Ответ 2
Если строго один пробел является разделителем,
вероятно, std::getline
.
Например:
int main() {
using namespace std;
istringstream iss("This is a string");
string s;
while ( getline( iss, s, ' ' ) ) {
printf( "`%s'\n", s.c_str() );
}
}
Ответ 3
Можете ли вы использовать boost?
samm$ cat split.cc
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <string>
#include <vector>
int
main()
{
std::string split_me( "hello world how are you" );
typedef std::vector<std::string> Tokens;
Tokens tokens;
boost::split( tokens, split_me, boost::is_any_of(" ") );
std::cout << tokens.size() << " tokens" << std::endl;
BOOST_FOREACH( const std::string& i, tokens ) {
std::cout << "'" << i << "'" << std::endl;
}
}
выполнение примера:
samm$ ./a.out
8 tokens
'hello'
'world'
''
'how'
'are'
''
''
'you'
samm$
Ответ 4
Если вы не хотите повышать, вы можете использовать обычный старый operator>>
, а также std::noskipws
:
EDIT: обновления после тестирования.
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <sstream>
void split(const std::string& str, std::vector<std::string>& v) {
std::stringstream ss(str);
ss >> std::noskipws;
std::string field;
char ws_delim;
while(1) {
if( ss >> field )
v.push_back(field);
else if (ss.eof())
break;
else
v.push_back(std::string());
ss.clear();
ss >> ws_delim;
}
}
int main() {
std::vector<std::string> v;
split("hello world how are you", v);
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "-"));
std::cout << "\n";
}
http://ideone.com/62McC
Ответ 5
Если вы не прочь повысить, boost.tokenizer достаточно гибкий, чтобы решить эту проблему.
#include <string>
#include <iostream>
#include <boost/tokenizer.hpp>
void split_and_show(const std::string s)
{
boost::char_separator<char> sep(" ", "", boost::keep_empty_tokens);
boost::tokenizer<boost::char_separator<char> > tok(s, sep);
for(auto i = tok.begin(); i!=tok.end(); ++i)
std::cout << '"' << *i << "\"\n";
}
int main()
{
split_and_show("This is a string");
split_and_show("This is a string");
}
test: https://ideone.com/mN2sR
Ответ 6
Вы также можете использовать старый стиль 'strtok'
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
Он немного воинственный, но не предполагает использования boost (не то, что повышение - это плохо).
В основном вы вызываете strtok со строкой, которую хотите разбить, и разделителем (в данном случае пробелом), и он вернет вам char *.
Из ссылки:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
Ответ 7
Вы можете использовать простую функцию strtok() (*) Отсюда. Обратите внимание, что маркеры создаются на разделителях
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This is a string";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}