2017-02-27 1 views
2

Dies ist das Gegenteil von How to convert a vector<char*> to a vector<string>/string Frage.Wie konvertiert man einen Vektor <string> in einen Vektor <char*>

Ich habe einige Legacy-Routine, die mit vector<char*> funktioniert, also muss ich meine vector<string> umwandeln.

Hier ist, was ich komme mit:

std::vector<char*> charVec(strVec.size(),nullptr); 
for (int i=0; i<strVec.size();i++) { 
    charVec[i]= new char(strVec[i].size()+1); 
    charVec[i][strVec[i].copy(charVec[i], strVec[i].size())] = '\0'; 
} 

Ist das richtig?

Gibt es einen besseren Weg, es zu implementieren?


p.s. natürlich am Ende habe ich:

for (int i=0; i<strVec.size();i++) { 
    delete charVec[i]; 
} 
+0

Was ist Ihre Frage? –

+1

Haben Sie eine Frage? sieht aus, als ob Sie es bereits implementiert haben – vu1p3n0x

+1

Es hängt davon ab, ob der neue Vektor seine Strings besitzen muss oder nur eine temporäre Ansicht der Strings im anderen Vektor benötigt. – Galik

Antwort

6

Ein schneller Weg, dies zu tun, ist

std::vector<const char*> charVec(strVec.size(),nullptr); 
for (int i=0; i<strVec.size();i++) { 
    charVec[i]= strVec[i].c_str(); 
} 

und dann den resultierenden Vektor verwendet wird. Dies spart viel Zeit bei der Speicherzuweisung für große Datenmengen.

+0

Ihr Ergebnisvektor muss 'std :: vector ' sein. 'const char *' kann nicht zugewiesen werden 'char *' – MRB

+0

Danke, ich habe meine Antwort korrigiert. Ich vergesse immer, dass c_str einen konstanten Zeiger zurückgibt. – JeremiahB

2

Sie einfach string::c_str() bekommen die Zeichenfolge aus einem std :: string verwenden könnte. Lesen Sie mehr in How to convert a std::string to const char* or char*?

Oder Sie könnten nur ein wenig den Körper der Funktion ändern, aber nur Sie wissen, ob es das wert ist.


Natürlich als ssell in den Kommentaren erwähnt, denken Sie daran, dass Sie mit diesem Ansatz brauchen nicht die Saiten zu zerstören, wenn man sie behandeln! Es ist ein Kompromiss, Sie vermeiden die Kopie (so cool), aber Sie müssen aufpassen, nicht Müll zu lesen (falls Sie Ihre Zeichenfolgen löschen)!

+0

Ich würde 'std :: string :: c_str' nicht empfehlen, da es nicht sicher ist. Wenn eines seiner ursprünglichen 'std :: string' Objekte zerstört wird, wird die' char * 'Zeichenfolge ungültig. Es ist besser, die Daten zu kopieren, wie er es in seiner Frage tut, und andere tun es in ihren Antworten. Siehe [Was ist std :: string :: c_str() lifetime?] (Http://stackoverflow.com/questions/6456359/what-is-stdstringc-str-lifetime). – ssell

+0

@Sell guter Punkt, aber ich würde nicht mit der "nicht berühren" -Richtlinie gehen, würde ich mehr die Verwendung mit Vorsicht, werde ich aktualisieren! – gsamaras

+1

Wenn er eine strenge Kontrolle über den Umfang hat, dann ist Ihre Antwort die einfachste. Ich wollte nur vor den möglichen Gefahren warnen. – ssell

3

Warum reservieren Sie einen neuen Puffer für Ihre Strings? Sie übergeben einen vector Zeichenzeiger an eine Funktion und schließlich löschen zugewiesene Puffer. Dies bedeutet, dass diese Puffer temporär sind und für sie kein Speicher reserviert werden muss, solange die Quelle vector (vector<string>) existiert.

Sie können dies ganz einfach:

std::vector<std::string> vec1 = { "1", "2", "3" }; 
std::vector<const char*> vec2; 

vec2.resize(vec1.size(), nullptr); 

std::transform(std::begin(vec1), std::end(vec1), std::begin(vec2), [&](const std::string& str) 
{ 
    return str.c_str(); 
}); 
+0

Oder Sie können 'vec2.resize()' mit 'vec2.reserve()' ersetzen und dann 'std :: back_inserter (vec2)' als Ausgabe-Iterator verwenden. –

+0

@RemyLebeau Natürlich, guter Punkt. Ich hatte 'std :: back_inserter' vergessen. Danke für die Erinnerung. – MRB

3

Ihre new Aussage falsch aussieht. Sie möchten ein Array von char lange genug zuordnen, um die Zeichenfolge zu halten. Sie weisen eine einzige char zu, deren Wert die Länge der Zeichenfolge ist. Ich bin überrascht, dass Sie keine Compilerwarnungen erhalten haben.

Versuchen Sie folgendes:

std::vector<char*> charVec; 
for (const auto &str : strVec) { 
    char *charStr = new char[str.size() + 1]; 
    std::strcpy(charStr, str.c_str()); 
    charVec.push_back(charStr); 
} 

Der einzige Nachteil ist, dass hier, wenn eine der Saiten Nullzeichen eingebettet ist, nichts als die bereits kopiert. Aber ich vermute, dass eine Funktion, die einen Vektor von char * nimmt, sich fast sicher nicht darum kümmert.

Verwandte Themen