Ich versuche, alle Elemente eines statischen Arrays von Zeichenfolgen bestmöglich zu durchlaufen. Ich möchte in der Lage sein, es in einer Zeile zu deklarieren und Elemente einfach hinzuzufügen / zu entfernen, ohne die Nummer verfolgen zu müssen. Klingt wirklich einfach, nicht wahr?
Mögliche Nichtlösungen:
vector<string> v;
v.push_back("abc");
b.push_back("xyz");
for(int i = 0; i < v.size(); i++)
cout << v[i] << endl;
Probleme - keine Möglichkeit, den Vektor in einer Zeile mit einer Liste von Zeichenfolgen zu erstellen
Mögliche Nichtlösung 2:
string list[] = {"abc", "xyz"};
Probleme - keine Möglichkeit, die Anzahl der Zeichenfolgen automatisch zu ermitteln (von denen ich weiß).
Es muss einen einfachen Weg geben, dies zu tun.
Antworten:
C ++ 11 hat Initialisierungslisten hinzugefügt, um die folgende Syntax zu ermöglichen:
Die Unterstützung für diese C ++ 11-Funktion wurde in mindestens GCC 4.4 und nur in Visual Studio 2013 hinzugefügt .
quelle
Sie können a
vector<string>
aus einem statisch erstelltenchar*
Array präzise initialisieren :Dadurch werden übrigens alle Zeichenfolgen kopiert, sodass Sie den doppelten Speicher verwenden. Sie können Will Deans Vorschlag verwenden, um die magische Nummer 3 hier durch Arraysize (str_array) zu ersetzen - obwohl ich mich erinnere, dass es einen Sonderfall gibt, in dem diese bestimmte Version von Arraysize möglicherweise etwas Schlechtes bewirkt (Entschuldigung, ich kann mich nicht sofort an die Details erinnern). . Aber es funktioniert sehr oft richtig.
Wenn Sie sich wirklich für das Ding mit einer Zeile interessieren, können Sie auch ein variadisches Makro definieren, sodass eine einzelne Zeile wie z
DEFINE_STR_VEC(strvector, "hi", "there", "everyone");
.quelle
strarray
Verstößt es nicht gegen die One-Definition-Regel, da es sich in einem Header befindet?Es gibt eine Standardmethode, bei der viele Leute (einschließlich MS) Makros definieren wie
arraysize
:quelle
template<typename T, size_t N> inline size_t arraysize(T (&ar)[N]) { return N; }
(Inline-Schlüsselwort nicht erforderlich, aber zur Dokumentation der Absicht der Funktion verwendet. Ein moderner Compiler sollte theoretisch in der Lage sein, die gesamte Funktion zurückzugeben, glaube ich.Deklarieren Sie ein Array von Zeichenfolgen in C ++ wie folgt:
char array_of_strings[][]
Zum Beispiel :
char array_of_strings[200][8192];
enthält 200 Zeichenfolgen, wobei jede Zeichenfolge die Größe 8 KB oder 8192 Byte hat.
Verwenden Sie
strcpy(line[i],tempBuffer);
diese Option, um Daten in das Array von Zeichenfolgen einzufügen.quelle
array_of_strings
Verstößt es nicht gegen die One-Definition-Regel, da es sich in einem Header befindet?Eine Möglichkeit besteht darin, einen NULL-Zeiger als Flag-Wert zu verwenden:
quelle
char*
. Im Speicher wird dies als 3 Zeiger dargestellt - einer zeigt auf "Hund", einer zeigt auf "Katze" und einer bleibt NULL. Ich kann einen Zeiger auf diesen ersten Zeiger nehmen undchar**
einen Zeiger auf den Zeiger auf char bekommen. Wenn ich das inkrementiere, bewege ich das Zeichen **, um auf das nächste Element in der Liste zu zeigen - einen Zeiger auf den Zeiger, der auf "cat" zeigt, dann inkrementiere ich erneut und erhalte einen Zeiger, der auf den NULL-Zeiger zeigt, und Ich weiß, dass ich fertig bin. (Sie können die Funktionen
begin
undend
aus der Boost-Bereichsbibliothek verwenden, um die Enden eines primitiven Arrays leicht zu finden. Im Gegensatz zur Makrolösung führt dies zu einem Kompilierungsfehler anstelle eines fehlerhaften Verhaltens, wenn Sie ihn versehentlich auf einen Zeiger anwenden.quelle
Der Fall, in dem es nicht funktioniert, ist, wenn das "Array" wirklich nur ein Zeiger ist, kein tatsächliches Array. Aufgrund der Art und Weise, wie Arrays an Funktionen übergeben werden (in einen Zeiger auf das erste Element konvertiert), funktioniert es auch nicht über Funktionsaufrufe hinweg, selbst wenn die Signatur wie ein Array aussieht -
some_function(string parameter[])
ist es wirklichsome_function(string *parameter)
.quelle
Hier ist ein Beispiel:
quelle
Anstelle dieses Makros könnte ich dieses vorschlagen:
1) Wir möchten ein Makro verwenden, um es zu einer Konstante für die Kompilierungszeit zu machen. Das Ergebnis des Funktionsaufrufs ist keine Kompilierungszeitkonstante.
2) Wir möchten jedoch kein Makro verwenden, da das Makro versehentlich für einen Zeiger verwendet werden könnte. Die Funktion kann nur für Arrays zur Kompilierungszeit verwendet werden.
Wir verwenden also die Definiertheit der Funktion, um das Makro "sicher" zu machen. Wenn die Funktion vorhanden ist (dh eine Größe ungleich Null hat), verwenden wir das Makro wie oben. Wenn die Funktion nicht existiert, geben wir einen schlechten Wert zurück.
quelle
quelle
quelle
Sie können ein Array von Zeichenfolgen wie direkt deklarieren
string s[100];
. Wenn Sie dann auf bestimmte Elemente zugreifen möchten, können Sie es direkt wie erhaltens[2][90]
. Nehmen Sie für Iterationszwecke die Größe der Zeichenfolge mithilfe ders[i].size()
Funktion.quelle