J'essaye d'itérer sur tous les éléments d'un tableau statique de chaînes de la meilleure façon possible. Je veux pouvoir le déclarer sur une seule ligne et y ajouter / supprimer facilement des éléments sans avoir à garder une trace du numéro. Cela semble vraiment simple, n'est-ce pas?
Non-solutions possibles:
vector<string> v;
v.push_back("abc");
b.push_back("xyz");
for(int i = 0; i < v.size(); i++)
cout << v[i] << endl;
Problèmes - aucun moyen de créer le vecteur sur une ligne avec une liste de chaînes
Non-solution possible 2:
string list[] = {"abc", "xyz"};
Problèmes - aucun moyen d'obtenir le nombre de chaînes automatiquement (que je connaisse).
Il doit y avoir un moyen simple de le faire.
Réponses:
C ++ 11 a ajouté des listes d'initialisation pour autoriser la syntaxe suivante:
La prise en charge de cette fonctionnalité C ++ 11 a été ajoutée au moins dans GCC 4.4 et uniquement dans Visual Studio 2013 .
la source
Vous pouvez initialiser
vector<string>
de manière concise un à partir d'unchar*
tableau créé statiquement :Cela copie toutes les chaînes, en passant, vous utilisez donc deux fois la mémoire. Vous pouvez utiliser la suggestion de Will Dean pour remplacer le nombre magique 3 ici par arraysize (str_array) - bien que je me souvienne qu'il y a eu un cas particulier dans lequel cette version particulière de arraysize pourrait faire quelque chose de mal (désolé, je ne me souviens pas des détails immédiatement) . Mais cela fonctionne très souvent correctement.
De plus, si vous êtes vraiment enthousiasmé par le truc d'une ligne, vous pouvez définir une macro variadique pour qu'une seule ligne telle que
DEFINE_STR_VEC(strvector, "hi", "there", "everyone");
fonctionne.la source
strarray
trouve dans un en-tête, ne violera-t-il pas la règle de définition unique?Il existe une manière standard de faire cela, que beaucoup de gens (y compris MS) définissent des macros comme
arraysize
pour:la source
template<typename T, size_t N> inline size_t arraysize(T (&ar)[N]) { return N; }
(Le mot clé en ligne n'est pas nécessaire, mais utilisé pour documenter l'intention de la fonction. Un compilateur moderne devrait théoriquement être en mesure de retourner la fonction entière, je crois.Déclarez un tableau de chaînes en C ++ comme ceci:
char array_of_strings[][]
Par exemple :
char array_of_strings[200][8192];
contiendra 200 chaînes, chaque chaîne ayant la taille 8kb ou 8192 octets.
utilisez
strcpy(line[i],tempBuffer);
pour mettre des données dans le tableau de chaînes.la source
array_of_strings
trouve dans un en-tête, ne violera-t-il pas la règle de définition unique?Une possibilité est d'utiliser un pointeur NULL comme valeur d'indicateur:
la source
char*
. En mémoire, cela se présente sous la forme de 3 pointeurs - l'un pointe vers «chien», l'autre pointe vers «chat» et l'autre est laissé NULL. Je peux prendre un pointeur vers ce premier pointeur et obtenir unchar**
- un pointeur vers un pointeur vers char. Lorsque j'incrémente cela, je déplace le caractère ** pour qu'il pointe vers l'élément suivant dans la liste - un pointeur vers le pointeur qui pointe vers "chat", puis j'incrémente à nouveau et j'obtiens un pointeur qui pointe vers le pointeur NULL, et Je sais que j'ai fini. (Vous pouvez utiliser les fonctions
begin
etend
de la bibliothèque de plages Boost pour trouver facilement les extrémités d'un tableau primitif, et contrairement à la solution macro, cela donnera une erreur de compilation au lieu d'un comportement cassé si vous l'appliquez accidentellement à un pointeur.la source
Le cas où cela ne fonctionne pas est lorsque le "tableau" n'est en réalité qu'un pointeur, pas un tableau réel. De plus, en raison de la façon dont les tableaux sont passés aux fonctions (convertis en pointeur vers le premier élément), cela ne fonctionne pas entre les appels de fonction même si la signature ressemble à un tableau -
some_function(string parameter[])
c'est vraimentsome_function(string *parameter)
.la source
Voici un exemple:
la source
Au lieu de cette macro, pourrais-je suggérer celle-ci:
1) Nous voulons utiliser une macro pour en faire une constante à la compilation; le résultat de l'appel de fonction n'est pas une constante de compilation.
2) Cependant, nous ne voulons pas utiliser de macro car la macro pourrait être accidentellement utilisée sur un pointeur. La fonction ne peut être utilisée que sur des tableaux au moment de la compilation.
Donc, nous utilisons la définition de la fonction pour rendre la macro "sûre"; si la fonction existe (c'est-à-dire qu'elle a une taille non nulle) alors nous utilisons la macro comme ci-dessus. Si la fonction n'existe pas, nous renvoyons une valeur incorrecte.
la source
la source
la source
Vous pouvez déclarer directement un tableau de chaînes comme
string s[100];
. Ensuite, si vous souhaitez accéder à des éléments spécifiques, vous pouvez l'obtenir directement commes[2][90]
. À des fins d'itération, prenez la taille de la chaîne à l'aide de las[i].size()
fonction.la source