Analysieren eines durch Kommas getrennten std::string [duplicate]
Lesezeit: 6 Minuten
Wenn ich einen std::string habe, der eine durch Kommas getrennte Liste von Zahlen enthält, wie kann ich die Zahlen am einfachsten analysieren und in ein Integer-Array einfügen?
Ich möchte dies nicht verallgemeinern, um etwas anderes zu analysieren. Nur eine einfache Zeichenfolge aus durch Kommas getrennten Ganzzahlen wie “1,1,1,1,2,1,1,1,0”.
für alle, die suchen, wie man durch Kommas getrennte Zeichenfolgen analysiert stackoverflow.com/questions/11719538/…
– Sam B
4. September 2021 um 15:49 Uhr
Geben Sie jeweils eine Zahl ein und prüfen Sie, ob das folgende Zeichen ist ,. Wenn ja, verwerfen Sie es.
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
int main()
{
std::string str = "1,2,3,4,5,6";
std::vector<int> vect;
std::stringstream ss(str);
for (int i; ss >> i;) {
vect.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
for (std::size_t i = 0; i < vect.size(); i++)
std::cout << vect[i] << std::endl;
}
Ich denke, dies wird fehlschlagen, wenn vor dem ein Leerzeichen vorhanden ist.
– KeithB
12. Dezember 2009 um 23:09 Uhr
Ja, das wird es, aber Leerzeichen waren nicht Teil des ursprünglichen Problems
– Benutzer229321
12. Dezember 2009 um 23:12 Uhr
Um das abzudecken: if (ss.peek() == ',' || ss.peek() == ' ')
– safe_malloc
31. Oktober 2014 um 9:27 Uhr
Wie kann man es ändern, wenn man die Werte in ein Array bekommen soll? (Wenn die Anzahl der Elemente bereits bekannt ist)
– S.Dan
10. November 2014 um 12:22 Uhr
@safe_malloc: Sollte das nicht sein while (ss.peek() == ',' || ss.peek() == ' ')
– Saurabhöhen
10. Mai 2016 um 16:30 Uhr
Etwas weniger ausführlich, std und nimmt alles, was durch ein Komma getrennt ist.
Um dies zu nutzen, müssen Sie imbue() ein Stream mit einem Gebietsschema, das diese Facette enthält. Sobald Sie das getan haben, können Sie Zahlen lesen, als wären die Kommas überhaupt nicht vorhanden. Nur zum Beispiel lesen wir durch Kommas getrennte Zahlen aus der Eingabe und schreiben dann eine pro Zeile auf die Standardausgabe:
#include <algorithm>
#include <iterator>
#include <iostream>
int main() {
std::cin.imbue(std::locale(std::locale(), new csv_reader()));
std::copy(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
Die kreativste Antwort, die ich je gesehen habe!
– Joko
16. Mai 2011 um 16:37 Uhr
+1 verwendet nur std und es ist eine saubere und einfache Lösung. Kein Spähen und Ignorieren von Zeichen!
– kravemir
23. Februar 2013 um 14:30 Uhr
Hier ist ein funktionierendes Beispiel, falls jemand es ausprobieren wollte: ideone.com/RX5o10
– kravemir
23. Februar 2013 um 14:40 Uhr
Beachten Sie, dass das obige Beispiel explodiert, wenn die Eingabe wie “1, 2, 3, 4, 5 …” aussieht. Sie müssen die Zeile rc hinzufügen[‘ ‘] = ctype_base::space;. Ich brauchte eine Weile, um es herauszufinden
– eine Kurie
27. März 2013 um 19:35 Uhr
Ich fürchte, diese Lösung unterstützt jedoch keine leeren Zeichenfolgen, sie werden einfach übersprungen. Nehmen Sie zum Beispiel diese Eingabe: 1,2,3,,5,6,7.
wenn Sie Boost.Tokenizer verwenden, warum nicht ersetzen atoi durch boost::lexical_cast?
– Andriy Tylychko
9. Februar 2011 um 23:51 Uhr
Viele ziemlich schreckliche Antworten hier, also füge ich meine hinzu (einschließlich Testprogramm):
#include <string>
#include <iostream>
#include <cstddef>
template<typename StringFunction>
void splitString(const std::string &str, char delimiter, StringFunction f) {
std::size_t from = 0;
for (std::size_t i = 0; i < str.size(); ++i) {
if (str[i] == delimiter) {
f(str, from, i);
from = i + 1;
}
}
if (from <= str.size())
f(str, from, str.size());
}
int main(int argc, char* argv[]) {
if (argc != 2)
return 1;
splitString(argv[1], ',', [](const std::string &s, std::size_t from, std::size_t to) {
std::cout << "`" << s.substr(from, to - from) << "`\n";
});
return 0;
}
Schöne Eigenschaften:
Keine Abhängigkeiten (z. B. Boost)
Kein verrückter Einzeiler
Leicht verständlich (hoffe ich)
Behandelt Leerzeichen vollkommen in Ordnung
Weist keine Splits zu, wenn Sie dies nicht möchten, z. B. können Sie sie wie gezeigt mit einem Lambda verarbeiten.
Fügt Zeichen nicht einzeln hinzu – sollte schnell sein.
Wenn Sie C ++ 17 verwenden, können Sie es ändern, um a zu verwenden std::stringview und dann werden keine Zuweisungen vorgenommen und es sollte extrem schnell sein.
Einige Designoptionen, die Sie möglicherweise ändern möchten:
für alle, die suchen, wie man durch Kommas getrennte Zeichenfolgen analysiert stackoverflow.com/questions/11719538/…
– Sam B
4. September 2021 um 15:49 Uhr