Wie kann ich eine Zeichenfolge wie "102:330:3133:76531:451:000:12:44412
" durch das Zeichen ":
" aufteilen und alle Zahlen in ein int-Array schreiben (Zahlenfolge wird immer 8 sein)? Vorzugsweise ohne Verwendung einer externen Bibliothek wie boost.
Außerdem frage ich mich, wie ich nicht benötigte Zeichen aus der Zeichenfolge entfernen kann, bevor sie verarbeitet werden, beispielsweise "$" und "#".
stringstream
kann all dies tun.
Trennen Sie einen String und speichern Sie ihn im int-Array:
string str = "102:330:3133:76531:451:000:12:44412";
std::replace(str.begin(), str.end(), ':', ' '); // replace ':' by ' '
vector<int> array;
stringstream ss(str);
int temp;
while (ss >> temp)
array.Push_back(temp); // done! now array={102,330,3133,76531,451,000,12,44412}
Entfernen Sie nicht benötigte Zeichen aus der Zeichenfolge, bevor sie verarbeitet werden, z. B. $
und #
: genauso wie bei der Verarbeitung von :
oben.
Die Standardmethode in C ist die Verwendung von strtok
wie andere beantwortet haben. strtok
ist jedoch nicht C++
-ähnlich und auch unsicher . Die Standardmethode in C++ ist die Verwendung von std::istringstream
std::istringstream iss(str);
char c; // dummy character for the colon
int a[8];
iss >> a[0];
for (int i = 1; i < 8; i++)
iss >> c >> a[i];
Falls die Eingabe immer eine feste Anzahl solcher Token hat, kann sscanf
eine andere einfache Lösung sein
std::sscanf(str, "%d:%d:%d:%d:%d:%d:%d:%d", &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8);
Ich musste zuvor etwas Code schreiben und fand eine Frage zu Stack Overflow, um einen String nach Trennzeichen zu teilen. Hier ist die ursprüngliche Frage: link .
Sie können dies mit std::stoi
zum Erstellen des Vektors verwenden.
std::vector<int> split(const std::string &s, char delim) {
std::vector<int> elems;
std::stringstream ss(s);
std::string number;
while(std::getline(ss, number, delim)) {
elems.Push_back(std::stoi(number));
}
return elems;
}
// use with:
const std::string numbers("102:330:3133:76531:451:000:12:44412");
std::vector<int> numbers = split(numbers, ':');
Hier ist ein Weg ... nicht der klügste, aber schnell zu schreiben (8 Wiederholungen, die anscheinend eine Schleife rechtfertigen). Dieser Parsing-Ansatz ist sehr nützlich, also gut zu lernen. !(iss >> c)
stellt sicher, dass in der Zeichenfolge keine Leerzeichen nachgestellt werden.
std::istringstream iss(the_string);
char c;
int n[8];
if (iss >> n[0] >> c && c == ':' &&
iss >> n[1] >> c && c == ':' &&
iss >> n[2] >> c && c == ':' &&
iss >> n[3] >> c && c == ':' &&
iss >> n[4] >> c && c == ':' &&
iss >> n[5] >> c && c == ':' &&
iss >> n[6] >> c && c == ':' &&
iss >> n[7] && !(iss >> c))
...
Sie können strtok()
verwenden, um Ihre Zeichenfolge aufzuteilen, möglicherweise in while-Schleife.
Wenn Sie einen individuellen String erhalten, können Sie atoi(xxx)
für die Konvertierung in ints verwenden.
Wahr ! es gibt keine elven magie
Es hat irgendwie geantwortet hier
#include <cstring>
#include <iostream>
#include<cstdlib>
#include<vector>
int main()
{
char input[100] = "102:330:3133:76531:451:000:12:44412";
char *token = std::strtok(input, ":");
std::vector<int> v;
while (token != NULL) {
v.Push_back( std::strtol( token, NULL, 10 ));
token = std::strtok(NULL, ":");
}
for(std::size_t i =0 ; i < v.size() ; ++i)
std::cout << v[i] <<std::endl;
}
Demo hier
Um die Zeichen '#' und '$' zu entfernen, können Sie den Standardalgorithmus std::remove_if
verwenden. Wenn Sie jedoch die folgende Zeichenfolge "12 # 34" eingeben, wird nach dem Entfernen von "#" "1234" angezeigt. Wenn Sie möchten, dass der Ergebnisstring als "12 34" oder "12:34" angezeigt wird, sollten Sie anstelle von std::remove_if
std::replace_if
verwenden.
Darunter befindet sich ein Beispielcode, der die Aufgabe ausführt. Sie müssen Header hinzufügen
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
int main()
{
char s[] = "102:$$330:#3133:76531:451:000:$12:44412";
std::cout << s << std::endl;
char *p = std::remove_if( s, s + std::strlen( s ),
[]( char c ) { return ( c == '$' || c == '#' ); } );
*p = '\0';
std::cout << s << std::endl;
const size_t N = 8;
int a[N];
p = s;
for ( size_t i = 0; i < N; i++ )
{
a[i] = strtol( p, &p, 10 );
if ( *p == ':' ) ++p;
}
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
}
Die Ausgabe ist
102:$$330:#3133:76531:451:000:$12:44412
102:330:3133:76531:451:000:12:44412
102 330 3133 76531 451 0 12 44412
#include <string.h>
int main ()
{
char str[] ="102:330:3133:76531:451:000:12:44412";
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;
}
Eine andere Lösung, die die regulären Ausdrücke in C++ 11 verwendet.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <regex>
#include <sstream>
#include <string>
#include <vector>
int main()
{
const std::string s = "102:330:3133:76531:451:000:12:44412";
// Replace each colon with a single space
const std::regex pattern(":");
const std::string r = std::regex_replace(s, pattern, " ");
std::istringstream ist(r);
std::vector<int> numbers;
std::copy(std::istream_iterator<int>(ist), std::istream_iterator<int>(),
std::back_inserter(numbers));
// We now have a vector of numbers
// Print it out
for (auto n : numbers)
{
std::cout << n << " ";
}
std::cout << std::endl;
return 0;
}