Comment imprimer le contenu d'un vecteur?
Je veux imprimer le contenu d'un vecteur en C++, voici ce que j'ai:
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sstream>
#include <cstdio>
using namespace std;
int main()
{
ifstream file("maze.txt");
if (file) {
vector<char> vec(istreambuf_iterator<char>(file), (istreambuf_iterator<char>()));
vector<char> path;
int x = 17;
char entrance = vec.at(16);
char firstsquare = vec.at(x);
if (entrance == 'S') {
path.push_back(entrance);
}
for (x = 17; isalpha(firstsquare); x++) {
path.push_back(firstsquare);
}
for (int i = 0; i < path.size(); i++) {
cout << path[i] << " ";
}
cout << endl;
return 0;
}
}
Comment puis-je imprimer le contenu du vecteur à l'écran?
- pourquoi est-il "ne fonctionne pas"?
Vous devez vous connecter pour publier un commentaire.
Purement pour répondre à votre question, vous pouvez utiliser un itérateur:
Si vous souhaitez modifier le vecteur contenu dans la boucle, puis utilisez
iterator
plutôt queconst_iterator
.Mais il y a beaucoup plus qui peut être dit au sujet de cette. Si vous voulez juste une réponse, vous pouvez utiliser, alors vous pouvez arrêter ici; sinon, lisez la suite.
auto (C++11)/typedef
Ce n'est pas une autre solution, mais un complément à ce qui précède
iterator
solution. Si vous êtes en utilisant le C++11 (ou version ultérieure), vous pouvez utiliser leauto
mot-clé pour aider à la lisibilité:Mais le type de
i
sera non-const (c, le compilateur utiliserastd::vector<char>::iterator
que le type dei
).Dans ce cas, vous pourriez tout aussi bien utiliser un
typedef
(pas de restriction de C++11, et très utile de l'utiliser de toute façon):contre
Vous pouvez, bien sûr, utiliser un type entier pour enregistrer votre position dans le
for
boucle:Si vous allez pour ce faire, il est préférable d'utiliser le conteneur types de membres, si elles sont disponibles et appropriées.
std::vector
a un type de membre appelésize_type
pour ce travail: c'est le type retourné par lesize
méthode.Pourquoi ne pas utiliser cette sur la
iterator
solution? Pour les cas simples, vous pourriez aussi bien, mais le point est que leiterator
classe est un objet conçu pour faire ce travail pour plus des objets compliqués où cette solution n'est pas idéale.gamme à base de boucle (C++11)
Voir Jefffrey de la solution. En C++11 (et plus tard), vous pouvez utiliser la nouvelle gamme à base de
for
boucle, qui ressemble à ceci:Depuis
path
est un vecteur d'éléments (explicitementstd::vector<char>
), l'objeti
est de type de l'élément du vecteur (c'est à dire, explicitement, il est de typechar
). L'objeti
a une valeur qui est une copie de l'élément dans lapath
objet. Ainsi, toutes les modifications apportées ài
dans la boucle ne sont pas conservées danspath
lui-même. En outre, si vous souhaitez faire respecter le fait que vous ne voulez pas être en mesure de modifier la valeur copiée dei
dans la boucle, vous pouvez forcer le type dei
êtreconst char
comme ceci:Si vous souhaitez modifier les éléments dans
path
, vous pouvez utiliser une référence:et même si vous ne voulez pas modifier les
path
, si la copie d'objets est cher vous devez utiliser const référence au lieu de la copie par valeur:std::copy
Voir Joshua répondre. Vous pouvez utiliser la STL algorithme
std::copy
pour copier le vecteur de contenu sur le flux de sortie. C'est une solution élégante, si vous êtes à l'aise avec elle (et d'ailleurs, il est très utile, pas seulement dans ce cas de l'impression du contenu d'un vecteur).std::for_each
Voir Max est la solution. À l'aide de
std::for_each
est overkill pour ce scénario simple, mais c'est une solution très pratique si vous voulais faire plus que juste l'impression à l'écran: à l'aide destd::for_each
vous permet de faire des tout (sensible) de l'opération sur le vecteur contenu.surcharge ostream::operator<<
Voir Chris répondre, c'est plus un complément à d'autres réponses car vous en aurez toujours besoin de mettre en œuvre l'une des solutions ci-dessus dans la surcharge. Dans son exemple, il a utilisé un compteur dans une
for
boucle. Par exemple, c'est comment vous pouvez rapidement utiliser Joshua solution:L'utilisation de l'un quelconque des autres solutions doivent être simples.
conclusion
Aucune des solutions présentées ici fonctionne. C'est à vous et le code sur lequel est le "meilleur". Quelque chose de plus détaillé que ce soit probablement le meilleur à gauche pour une autre question à laquelle les avantages/inconvénients peuvent être correctement évalués; mais, comme toujours, de préférence de l'utilisateur seront toujours de la partie: aucune des solutions présentées sont faux, mais certains vont regarder de plus agréable pour chaque codeur.
additif
C'est une expansion de la solution d'un précédent que j'ai posté. Depuis que la poste a continué de faire attention, j'ai décidé d'élargir et d'en référer à l'autre d'excellentes solutions qui ont été posté ici. Mon post original a une remarque qui dit que si vous ont été l'intention de modifier votre vecteur à l'intérieur d'un
for
boucle puis il y a deux méthodes fournies parstd::vector
d'accéder à des éléments:std::vector::operator[]
qui ne fait pas la vérification des limites, etstd::vector::at
qui effectue la vérification des limites. En d'autres termes,at
va jeter si vous essayez d'accéder à un élément en dehors du vecteur etoperator[]
ne serait pas. J'ai seulement ajouté ce commentaire, à l'origine, pour le bien de parler de quelque chose qu'il pourrait être utile de savoir si les gens déjà n'ai pas. Et je vois pas de différence. D'où le présent avenant.0
parvector::size()
et le vecteur n'est pas modifiée dans la boucle, il n'est pas nécessaire d'utiliserat()
et en subir les extra vérification de limite de surcharge. Cela dit, je voudrais aller avec un itérateur comme vous le suggérez.at
si de rien dans la boucle modifie le vecteur, mais j'ai pensé que je le mentionne juste au cas où le vecteur est modifiée dans la boucle (obsolète que cela puisse être) et parce qu'il n'est jamais en parler et il peut être utile, au moins, de savoir de lui.for (auto const &i: path) std::cout << i << ' ';
Un moyen beaucoup plus facile de le faire est avec la norme algorithme de copie:
La ostream_iterator est ce qu'on appelle une itérateur adaptateur. Il est templatized sur le texte à imprimer pour le flux de données (dans ce cas,
char
).cout
(aka sortie de la console) est le flux nous voulons écrire à, et le caractère espace (" "
) est ce que nous voulons imprimée entre chaque élément stocké dans le vecteur.Cet algorithme standard est puissant et il en est beaucoup d'autres. La puissance et la flexibilité de la bibliothèque standard vous donne sont ce qui rend si grand. Imaginez: vous pouvez imprimer un vecteur de la console avec juste un ligne de code. Vous n'avez pas à traiter avec des cas particuliers avec le caractère de séparation. Vous n'avez pas besoin de s'inquiéter pour des boucles. La bibliothèque standard de fait tout pour vous.
vector<pair<int, struct node>>
. Comment puis-je utiliser la méthode ci-dessus pour imprimer ce vecteur?operator<<
fonction de votre paire<>.En C++11, vous pouvez désormais utiliser un gamme à base de boucle:
char
s, les chances sont que de passage par référence constante est en fait plus cher que par valeur. Mais ici, nous parlons de super micro optimisations.Je pense que la meilleure façon de le faire est de surcharge
operator<<
par l'ajout de cette fonction à votre programme:Ensuite, vous pouvez utiliser le
<<
opérateur sur n'importe quel vecteur possible, en supposant que ses éléments ont égalementostream& operator<<
définis:Sorties:
last
àsize_t
.size_t last = v.size() - 1;
semble redondant, vous pouvez utiliserif (i) out << ", ";
condition avantout << v[i];
lienoperator<<
. ExempleComment sur
for_each
+ lambda expression:Bien sûr, un gamme à base de est la solution la plus élégante pour cette tâche concrète, mais celui-ci offre de nombreuses autres possibilités.
Explication
La
for_each
algorithme prend un d'entrée de gamme et un objet appelable, l'appel de cette objet sur chaque élément de la gamme. Un d'entrée de gamme est définie par deux itérateurs. Un objet appelable peut être une fonction, un pointeur de fonction, un objet d'une classe qui surcharge() operator
ou comme dans ce cas, une expression lambda. Le paramètre de cette expression correspond au type des éléments du vecteur.La beauté de cette application est la puissance que vous obtenez à partir d'expressions lambda - vous pouvez utiliser cette approche pour beaucoup plus de choses que juste l'impression de le vecteur.
Il suffit de copier le conteneur à la console.
Doit de sortie :
Le problème est probablement dans le précédent boucle:
(x = 17; isalpha(firstsquare); x++)
. Cette boucle sera exécuté pas à tous (sifirstsquare
est non-alpha) ou s'exécute indéfiniment (si c'est de l'alpha). La raison en est quefirstsquare
ne change pas commex
est incrémenté.En C++11, une gamme à base de boucle peut être une bonne solution:
De sortie:
À l'aide de
std::copy
mais sans extra fin séparateurUne alternative/approche modifiée à l'aide de
std::copy
(comme à l'origine utilisé dans @JoshuaKravtiz répondre), mais sans le fait d'ajouter un séparateur à droite après le dernier élément:Exemple d'utilisation appliquée à conteneurs d'un type POD:
Je vois deux problèmes. Comme l'a souligné dans
for (x = 17; isalpha(firstsquare); x++)
il y a une boucle infinie ou jamais exécutée, et aussi dansif (entrance == 'S')
si l'entrée de caractères est différent de 'S' alors rien de poussé le chemin vecteur, rendant vide et donc l'impression de rien sur l'écran. Vous pouvez tester la dernière vérification pourpath.empty()
ou l'impressionpath.size()
.De toute façon, ça ne serait pas mieux d'utiliser une chaîne au lieu d'un vecteur? Vous pouvez accéder le contenu de la chaîne comme un tableau en tant que bien, de chercher des personnages, d'en extraire des sous-chaînes et imprimer la chaîne facilement (sans la boucle).
De le faire avec des chaînes peuvent être le moyen de l'avoir écrit dans un moins alambiqué façon et la plus facile à repérer le problème.
surcharge de l'opérateur<<:
Utilisation:
Cette réponse est fondée sur la réponse de Zorawar, mais je ne pouvais pas laisser un commentaire.
Vous pouvez faire de l'auto (C++11)/typedef version const en utilisant cbegin et cend au lieu
En C++11`
Vous pouvez écrire votre propre fonction:
Cela a fonctionné pour moi: