Comment déclarer un tableau de chaînes en C++?

j'essaie d'itérer tous les éléments d'un tableau statique de chaînes de la meilleure façon possible. Je veux être en mesure de le déclarer sur une ligne et facilement ajouter/supprimer des éléments sans avoir à garder une trace du nombre. Les sons très 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 - pas moyen de créer le vecteur sur une seule ligne avec une liste de chaînes

possibilité de non-solution 2:

string list[] = {"abc", "xyz"};

Problèmes - pas moyen d'obtenir le nombre de chaînes automatiquement (que je connais).

Il doit y avoir un moyen facile de le faire.

80
demandé sur LogicStuff 2008-08-29 22:41:35

15 réponses

Le boost affecter la bibliothèque semble être exactement ce que vous cherchez. Il rend l'assignation des constantes aux conteneurs plus facile que jamais.

27
répondu Craig H 2008-08-29 18:44:08

C++ 11 a ajouté des listes d'initialisation pour permettre la syntaxe suivante:

std::vector<std::string> v = {"Hello", "World"};

la prise en charge de cette fonctionnalité C++ 11 a été ajoutée dans au moins GCC 4.4 et seulement dans Visual Studio 2013 .

97
répondu Anthony Cramp 2015-06-25 09:52:38

vous pouvez initialiser de façon concise un vector<string> à partir d'un tableau char* créé statiquement:

char* strarray[] = {"hey", "sup", "dogg"};
vector<string> strvector(strarray, strarray + 3);

cela copie toutes les cordes, soit dit en passant, donc vous utilisez 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 avait un cas spécial 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 il très souvent, fonctionne correctement.

en outre, si vous êtes vraiment gung-ho sur le bidule d'une ligne, vous pouvez définir une macro variadique de sorte qu'une seule ligne comme DEFINE_STR_VEC(strvector, "hi", "there", "everyone"); fonctionne.

36
répondu Tyler 2008-08-29 21:21:08

Problèmes - pas moyen d'obtenir le nombre de chaînes automatiquement (que je connais).

il y a une méthode standard de faire ceci, que beaucoup de gens (y compris MS) définissent des macros comme arraysize pour:

#define arraysize(ar)  (sizeof(ar) / sizeof(ar[0]))
23
répondu Will Dean 2015-12-22 19:19:26

Déclarer un tableau de chaînes de caractères 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.

9
répondu 2012-01-11 14:09:20

une possibilité est d'utiliser un pointeur nul comme valeur du drapeau:

const char *list[] = {"dog", "cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
    cout << *iList;
}
7
répondu Eclipse 2008-09-15 19:48:19

vous pouvez utiliser les fonctions begin et end de la bibliothèque Boost range 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.

const char* array[] = { "cat", "dog", "horse" };
vector<string> vec(begin(array), end(array));
4
répondu Ross Smith 2015-12-22 19:20:12

vous pouvez utiliser la suggestion de Will Dean [ #define arraysize(ar) (sizeof(ar) / sizeof(ar[0])) ] pour remplacer le nombre magique 3 ici avec arraysize(str_array) -- bien que je me souvienne qu'il y avait un cas spécial 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.

Le cas où il ne fonctionne pas, c'est quand le "tableau" est vraiment juste un pointeur, pas un tableau. Également, en raison de la façon dont les tableaux sont passés aux fonctions (converties en pointeur vers le premier élément), il ne fonctionne pas à travers les appels de fonction même si la signature ressemble à un tableau - some_function(string parameter[]) est vraiment some_function(string *parameter) .

3
répondu Matthew Crumley 2008-08-29 21:34:43

a essayé D'annuler la réponse de Craig H que vous devriez utiliser boost:: assign, mais je n'ai pas de rep: (

j'ai rencontré une technique similaire dans le premier article que j'ai jamais lu par Andrei Alexandrescu dans C/C++ Utilisateurs Journal , Vol 16, N ° 9, septembre 1998, pp. 73-74 (disposer de l'intégralité de la citation parce que c'est dans les commentaires de ma mise en œuvre de son code que j'ai utilisé depuis).

Les modèles

sont vos amis.

3
répondu mlbrock 2008-09-15 22:06:46

au lieu de cette macro, puis-je suggérer celle-ci:

template<typename T, int N>
inline size_t array_size(T(&)[N])
{
    return N;
}

#define ARRAY_SIZE(X)   (sizeof(array_size(X)) ? (sizeof(X) / sizeof((X)[0])) : -1)

1) Nous voulons utiliser une macro pour faire une constante de compilation; l'appel de la fonction du résultat n'est pas une constante de compilation.

2) Cependant, nous ne voulons pas utiliser une macro parce que la macro pourrait être accidentellement utilisée sur un pointeur. La fonction ne peut être utilisée que sur des tableaux de compilation.

ainsi, nous utilisons le caractère défini de la fonction pour faire la macro "sûr"; si la fonction existe (c.-à-d. qu'elle a une taille non nulle) alors nous utilisons la macro comme ci-dessus. Si la fonction n'existe pas, nous revenons d'une mauvaise valeur.

2
répondu DrPizza 2008-09-01 01:05:36
#include <boost/foreach.hpp>

const char* list[] = {"abc", "xyz"};
BOOST_FOREACH(const char* str, list)
{
    cout << str << endl;
}
2
répondu 2008-09-06 05:34:36

voici un exemple:

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

int main() {
    const char* const list[] = {"zip", "zam", "bam"};
    const size_t len = sizeof(list) / sizeof(list[0]);

    for (size_t i = 0; i < len; ++i)
        std::cout << list[i] << "\n";

    const std::vector<string> v(list, list + len);
    std::copy(v.begin(), v.end(), std::ostream_iterator<string>(std::cout, "\n"));
}
2
répondu Shadow2531 2015-12-23 19:35:13
#include <iostream>
#include <string>
#include <vector>
#include <boost/assign/list_of.hpp>

int main()
{
    const std::vector< std::string > v = boost::assign::list_of( "abc" )( "xyz" );
    std::copy(
        v.begin(),
        v.end(),
        std::ostream_iterator< std::string >( std::cout, "\n" ) );
}
1
répondu Dominic.wig 2009-12-12 13:33:11
#include <iostream.h>
#include <iomanip.h>

int main()
{
int n;
cout<<"enter the maximum number\n";
cin>>n;
cout<<"enter the first number\n";
for(int i=0;i<n;i++)
{

for(int j=0;j<n;j++)
{
cin>>a[i][j];
}
}
cout<<"enter the second number\n";
for(int i=0;i<n;i++)
{
for(int k=0;k<n;k++)
{
cin>>b[i][k];
}
}
cout<<"the product will be\n";
for(int i=0;i<n;i++)
{
for(int g=0;g<n;g++)
{
c[i][g]=c[i][c]*c[i][j];
cout<<setw(5)<<c[i][g];
}
cout<<endl;
}
return 0;
}
1
répondu gashaye 2011-04-09 02:45:41

vous pouvez déclarer directement un tableau de chaînes comme string s[100]; . Ensuite, si vous voulez accéder à des éléments spécifiques, vous pouvez l'obtenir directement comme s[2][90] . Pour les besoins de l'itération, prendre la taille de la chaîne en utilisant le s[i].size() de la fonction.

1
répondu kajol jain 2016-01-28 17:52:20