void MyIntToChar(int *arrayOfInt, char* output);
C'est faux de plusieurs façons. Tout d'abord, c'est un abus de langage. Vous ne pouvez pas, en général, convertir un nombre entier en un caractère, car seulement dix de tous les intergers (0
... 9
) entreraient dans un. Donc, je suppose que vous voulez convertir des entiers en _strings à la place.
Ensuite, si vous passez des tableaux à des fonctions, ils se désintègrent en pointeurs vers leur premier élément, et toutes les informations sur la taille du tableau sont perdues. Ainsi, lorsque vous passez des tableaux à fonctionner, vous devez également transmettre des informations de taille.
Soit utiliser la voie C de faire cela et passer dans le nombre d'éléments que std::size_t
(à obtenir comme sizeof(myarray)/sizeof(myarray[0])
):
void MyIntToStr(int *arrayOfInt, std::size_t arraySize, char* output);
Ou faire les choses comme C++ et passer en deux itérateurs, une pointant vers le premier élément (soi-disant commencer itérateur) et l'autre pointant vers une derrière la dernière (fin itérateur):
void MyIntToStr(int *begin, int *end, char* output);
Vous pouvez améliorer que de ne pas insister sur les itérateurs étant int*
, mais tout ce qui, quand déréférencé, donne un int
:
template< typename FwdIt >
void MyIntToStr(FwdIt begin, FwdIt end, char* output);
(. Les modèles devraient vous obliger à mettre en œuvre l'algorithme dans un en-tête)
Ensuite, il y a les problèmes avec la sortie. Tout d'abord, attendez-vous vraiment tous les numéros à écrire dans une chaîne? Si oui, comment devraient-ils être séparés? Rien? Espace blanc? Virgule?
Ou pensez-vous qu'un tableau de chaînes sera renvoyé?
En supposant que vous voulez vraiment une chaîne, si je passe le tableau {1, 2, 3, 4, 5}
dans votre fonction, il a besoin d'espace pour cinq entiers à un seul chiffre, plus l'espace nécessaire pour quatre séparateurs. Votre signature de fonction suggère que vous vouliez que je l'attribue d'avance, mais franchement, si je dois calculer moi-même, je ferais aussi bien de faire les conversions moi-même. En outre, je n'ai aucun moyen de vous dire combien de mémoire char*
points, de sorte que vous ne pouvez pas vérifier si j'avais raison. Comme l'ont découvert des générations de développeurs, il est si difficile d'obtenir à chaque fois que plusieurs langages informatiques ont été inventés pour faciliter les choses aux programmeurs. L'un de ceux-ci est C++, qui vient aujourd'hui avec une classe de chaîne de redimensionnement dynamique.
Il serait beaucoup plus facile (pour vous et pour moi), si je pouvais vous passer un stirng et vous écrivez dans ce:
template< typename FwdIt >
void MyIntToChar(FwdIt begin, FwdIt end, std::string& output);
Notez que je passe ce la chaîne par référence non const
. Cela vous permet de modifier ma chaîne et de voir les modifications que vous avez faites.
Cependant, une fois que nous faisons cela, vous pourriez tout aussi bien revenir une nouvelle chaîne au lieu de me requireing passer un à vous:
template< typename FwdIt >
std::string MyIntToChar(FwdIt begin, FwdIt end);
Cependant, si vous voulez vraiment un tableau de chaînes renvoyées, vous ne devriez pas prendre une chaîne à écrire, mais un moyen où les écrire. La façon naïve de le faire serait de passer un tableau dynamiquement re-sizable de chaîne dynamiquement re-taille. En C++, ceci est écrit std::vector<std::string>
:
template< typename FwdIt >
void MyIntToStr(FwdIt begin, FwdIt end, std::vector<std::string>& output);
Encore une fois, il pourrait être préférable que vous retour un tel tableau (bien que certains seraient en désaccord depuis la copie d'un tableau de chaîne peut être considéré comme cher).Cependant, le meilleur moyen de le faire ne m'obligerait pas à accepter le résultat sous la forme d'un 'std :: vector'. Et si j'avais besoin des chaînes dans une liste (liée) à la place? Ou écrit dans un flux?
La meilleure façon de le faire serait pour votre fonction d'accepter un itérateur de sortie auquel vous écrivez votre résultat:
template< typename FwdIt, typename OutIt >
void MyIntToStr(FwdIt begin, FwdIt end, OutIt output);
Bien sûr, maintenant c'est si général qu'il est difficile de voir ce qu'il fait, donc c'est bon on lui a donné un bon nom. Cependant, en regardant cela, je pense immédiatement que cela devrait s'appuyer sur une autre fonction qui est probablement nécessaire encore plus que celui-ci: Une fonction qui prend un entier et le convertit en une chaîne. En supposant que nous avons une telle fonction:
std::string MyIntToStr(int i);
il est très facile à mettre en œuvre les versions du tableau:
template< typename FwdIt, typename OutIt >
void MyIntToStr(FwdIt begin, FwdIt end, OutIt output)
{
while(begin != end)
*output++ = MyIntToStr(*begin++);
}
Maintenant, tout ce qui vous reste à faire est de mettre en œuvre cette fonction std::string MyIntToStr(int i);
. Comme quelqu'un l'a déjà écrit, cela se fait facilement en utilisant des chaînes de caractères et vous ne devriez pas avoir de problème pour trouver de bons exemples. Cependant, il est encore plus facile de trouver de mauvais exemples, donc je préfère vous donner un ici:
std::string MyIntToStr(int i);
{
std::ostringstream oss;
oss << i:
if(!oss) throw "bah!"; // put your error reporting mechanism here
return oss.str();
}
Bien sûr, les modèles donnés, facile à généraliser à accepter tout ce qui est diffusable:
template< typename T >
std::string MyIntToStr(const T& obj);
{
std::ostringstream oss;
oss << obj:
if(!oss) throw "bah!"; // put your error reporting mechanism here
return oss.str();
}
Notez que, compte tenu de ce modèle de fonction générale, le MyIntToStr()
travaillant sur les tableaux fonctionne maintenant automatiquement sur les tableaux de tout type sur lesquels travaille le modèle de fonction qui travaille sur un objet.
Ainsi, à la fin de ce (plutôt épique, je excuses) voyage, voici ce que nous sommes arrivés à: un modèle de fonction généralisée pour convertir quoi que ce soit (ce qui peut être écrit à un flux) dans une chaîne, et un modèle de fonction généralisé pour convertir le contenu de n'importe quel tableau d'objets (qui peuvent être écrits dans un flux) en un flux.
Notez que, si vous aviez au moins une douzaine de conférences 90mins sur C++ et vos instructeurs ne parvenez pas à vous assez apprendre à au moinscomprendrece que j'ai écrit ici, vous avezpasété bien enseigné selon les normes modernes d'enseignement C++.
Quel est l'antipath de std :: string et std :: vector?(Bien que si vous pensez que ce genre de chose viendra dans le test, assez juste) – Yacoby
Est-ce que 'void MyIntToChar (int * arrayOfInt, char * output)' partie de l'assignation parce qu'elle me ressemble, 'void MyIntToChar (std :: vector in, std :: string out) 'me ressemble plus au RPC. Vous devriez également clarifier votre question. –
Je suis certain que le test saute std :: string et vector. Je veux obtenir mes bases couvertes et puis (si j'ai le temps) passer en revue les conteneurs et la classe de corde dans le STL –