Προσπαθώ να επαναλάβω τις λέξεις μιας συμβολοσειράς.
Η συμβολοσειρά μπορεί να θεωρηθεί ότι αποτελείται από λέξεις που χωρίζονται από κενά.
Σημειώστε ότι δεν ενδιαφέρομαι για τις συναρτήσεις συμβολοσειρών της C ή αυτού του είδους τον χειρισμό/πρόσβαση χαρακτήρων. Επίσης, παρακαλώ δώστε προτεραιότητα στην κομψότητα έναντι της αποτελεσματικότητας στην απάντησή σας.
Η καλύτερη λύση που έχω αυτή τη στιγμή είναι η εξής:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string s = "Somewhere down the road";
istringstream iss(s);
do
{
string subs;
iss >> subs;
cout << "Substring: " << subs << endl;
} while (iss);
}
Υπάρχει ένας πιο κομψός τρόπος για να το κάνω αυτό;
Αυτός είναι ο αγαπημένος μου τρόπος για την επανάληψη σε μια συμβολοσειρά. Μπορείτε να κάνετε ό,τι θέλετε ανά λέξη.
string line = "a line of text to iterate through";
string word;
istringstream iss(line, istringstream::in);
while( iss >> word )
{
// Do something on `word` here...
}
Η STL δεν διαθέτει ήδη μια τέτοια μέθοδο.
Ωστόσο, μπορείτε είτε να χρησιμοποιήσετε τη συνάρτηση strtok()
της C χρησιμοποιώντας το μέλος std::string::c_str()
, είτε να γράψετε τη δική σας. Εδώ είναι ένα δείγμα κώδικα που βρήκα μετά από μια γρήγορη αναζήτηση στο Google ("STL string split"):
void Tokenize(const string& str,
vector<string>& tokens,
const string& delimiters = " ")
{
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
Λαμβάνεται από το: <http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html>,
Αν έχετε ερωτήσεις σχετικά με το δείγμα κώδικα, αφήστε ένα σχόλιο και θα σας εξηγήσω.
Και μόνο και μόνο επειδή δεν υλοποιεί ένα typedef
που ονομάζεται iterator ή δεν υπερφορτώνει τον τελεστή <<
δεν σημαίνει ότι είναι κακός κώδικας. Χρησιμοποιώ συναρτήσεις της C αρκετά συχνά. Για παράδειγμα, οι printf
και scanf
είναι και οι δύο ταχύτερες από τις std::cin
και std::cout
(σημαντικά), η σύνταξη της fopen
είναι πολύ πιο φιλική για δυαδικούς τύπους, και επίσης τείνουν να παράγουν μικρότερα EXE.
Μην σας πείσει αυτή η συμφωνία "Κομψότητα έναντι απόδοσης".
Η χρήση του std::stringstream
, όπως το έχετε κάνει, λειτουργεί τέλεια και κάνει ακριβώς αυτό που θέλατε. Αν όμως ψάχνετε για διαφορετικό τρόπο να κάνετε τα πράγματα, μπορείτε να χρησιμοποιήσετε std::find()
/std::find_first_of()
και std::string::substr()
.
Ακολουθεί ένα παράδειγμα:
#include <iostream>
#include <string>
int main()
{
std::string s("Somewhere down the road");
std::string::size_type prev_pos = 0, pos = 0;
while( (pos = s.find(' ', pos)) != std::string::npos )
{
std::string substring( s.substr(prev_pos, pos-prev_pos) );
std::cout << substring << '\n';
prev_pos = ++pos;
}
std::string substring( s.substr(prev_pos, pos-prev_pos) ); // Last word
std::cout << substring << '\n';
return 0;
}