Mögliches Duplikat: Wie teile ich
einen String?
Was ist der richtige Weg, um einen String in einen Vektor von Strings aufzuteilen? Trennzeichen ist Leerzeichen oder Komma.
Mögliches Duplikat: Wie teile ich
einen String?
Was ist der richtige Weg, um einen String in einen Vektor von Strings aufzuteilen? Trennzeichen ist Leerzeichen oder Komma.
Für durch Leerzeichen getrennte Zeichenfolgen können Sie Folgendes tun:
std::string s = "What is the right way to split a string into a vector of strings";
std::stringstream ss(s);
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::vector<std::string> vstrings(begin, end);
std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
Ausgabe:
What
is
the
right
way
to
split
a
string
into
a
vector
of
strings
struct tokens: std::ctype<char>
{
tokens(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
typedef std::ctype<char> cctype;
static const cctype::mask *const_rc= cctype::classic_table();
static cctype::mask rc[cctype::table_size];
std::memcpy(rc, const_rc, cctype::table_size * sizeof(cctype::mask));
rc[','] = std::ctype_base::space;
rc[' '] = std::ctype_base::space;
return &rc[0];
}
};
std::string s = "right way, wrong way, correct way";
std::stringstream ss(s);
ss.imbue(std::locale(std::locale(), new tokens()));
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::vector<std::string> vstrings(begin, end);
std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
Ausgabe:
right
way
wrong
way
correct
way
std::vector<std::string> vstrings(begin, end);
wäre schöner IMO, aber ich nehme an, wir wissen nicht, ob der Fragesteller den Vektor konstruiert oder hofft, einen bereits vorhandenen Vektor zu füllen.
ss.imbue(std::locale(std::locale(), new tokens()))
irgendwo erstellte Token-Struktur löschen ?
auto loc = std::make_shared<tokens>()
und dann übergeben ss.imbue(..., loc.get()));
. Das sollte funktionieren.
Ein bequemer Weg wäre die String-Algorithmus-Bibliothek von Boost .
#include <boost/algorithm/string/classification.hpp> // Include boost::for is_any_of
#include <boost/algorithm/string/split.hpp> // Include for boost::split
// ...
std::vector<std::string> words;
std::string s;
boost::split(words, s, boost::is_any_of(", "), boost::token_compress_on);
vector<string> split(string str, string token){
vector<string>result;
while(str.size()){
int index = str.find(token);
if(index!=string::npos){
result.push_back(str.substr(0,index));
str = str.substr(index+token.size());
if(str.size()==0)result.push_back(str);
}else{
result.push_back(str);
str = "";
}
}
return result;
}
split ("1,2,3", ",") ==> ["1", "2", "3"]
split ("1,2,", ",") ==> ["1", "2", ""]
split ("1token2token3", "token") ==> ["1", "2", "3"]
Sie können getline mit Trennzeichen verwenden:
string s, tmp;
stringstream ss(s);
vector<string> words;
while(getline(ss, tmp, ',')){
words.push_back(tmp);
.....
}
Wenn die Zeichenfolge sowohl Leerzeichen als auch Kommas enthält, können Sie die Zeichenfolgenklassenfunktion verwenden
found_index = myString.find_first_of(delims_str, begin_index)
in einer Schleife. Nach! = Npos suchen und in einen Vektor einfügen. Wenn Sie alte Schule bevorzugen, können Sie auch Cs verwenden
strtok()
Methode.
Optimierte Version von Techie Delight :
#include <string>
#include <vector>
std::vector<std::string> split(const std::string& str, char delim) {
std::vector<std::string> strings;
size_t start;
size_t end = 0;
while ((start = str.find_first_not_of(delim, end)) != std::string::npos) {
end = str.find(delim, start);
strings.push_back(str.substr(start, end - start));
}
return strings;
}
Ich habe diese benutzerdefinierte Funktion gemacht, die die Linie in Vektor konvertiert
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
using namespace std;
int main(){
string line;
getline(cin, line);
int len = line.length();
vector<string> subArray;
for (int j = 0, k = 0; j < len; j++) {
if (line[j] == ' ') {
string ch = line.substr(k, j - k);
k = j+1;
subArray.push_back(ch);
}
if (j == len - 1) {
string ch = line.substr(k, j - k+1);
subArray.push_back(ch);
}
}
return 0;
}
std::vector<std::string> split(std::string text, char delim) {
std::string line;
std::vector<std::string> vec;
std::stringstream ss(text);
while(std::getline(ss, line, delim)) {
vec.push_back(line);
}
return vec;
}
split("String will be split", ' ')
-> {"String", "will", "be", "split"}
split("Hello, how are you?", ',')
-> {"Hello", "how are you?"}
Ich schreibe diese benutzerdefinierte Funktion, die Ihnen helfen wird. Aber diskutieren Sie über die zeitliche Komplexität.
std::vector<std::string> words;
std::string s;
std::string separator = ",";
while(s.find(separator) != std::string::npos){
separatorIndex = s.find(separator)
vtags.push_back(s.substr(0, separatorIndex ));
words= s.substr(separatorIndex + 1, s.length());
}
words.push_back(s);