Question

J'ai des nombres de longueurs différentes (comme 1, 999, 76492, etc.) et je souhaite les convertir en chaînes de même longueur (par exemple, si la longueur est 6, ces chaînes seront: "000001", "000999", "076492").

En d'autres termes, je dois ajouter la quantité correcte de zéros non significatifs au nombre.

int n = 999;
string str = some_function(n,6);
//str = '000999'

Existe-t-il une fonction comme celle-ci en C ++?

Était-ce utile?

La solution

ou en utilisant les stringstreams:

#include <sstream>
#include <iomanip>

std::stringstream ss;
ss << std::setw(10) << std::setfill('0') << i;
std::string s = ss.str();

J'ai compilé les informations que j'ai trouvées sur arachnoid.com parce que j'aime le type- moyen sûr de plus iostreams. En outre, vous pouvez également utiliser ce code sur n’importe quel autre flux de sortie.

Autres conseils

char str[7];
snprintf (str, 7, "%06d", n);

Voir snprintf

Une chose que vous voudriez savoir, c'est le verrouillage potentiel qui peut se produire lorsque vous utilisez l'approche stringstream . Dans la STL livrée avec Visual Studio 2008, au moins, de nombreux verrous sont retirés et publiés, car diverses informations sur les paramètres régionaux sont utilisées lors du formatage. Cela peut être ou ne pas être un problème pour vous en fonction du nombre de threads que vous avez qui pourraient convertir simultanément des nombres en chaînes ...

La version sprintf ne prend pas de verrou (du moins selon l'outil de surveillance des verrous que je suis en train de développer ...) et pourrait donc être "mieux" utilisée dans situations concurrentes.

Je l’ai seulement remarqué parce que mon outil a récemment craché les verrous de "paramètres régionaux" parmi les verrous les plus contestés de mon système de serveur; cela a été un peu surprenant et pourrait me amener à réviser l’approche que j’avais choisie (c’est-à-dire revenir vers sprintf à partir de stringstream ) ...

stringstream fera ( comme xtofl a souligné ). Le format Boost est plus pratique remplacement pour snprintf.

Cette méthode n'utilise pas de flux ni sprintf. Outre les problèmes de verrouillage, les flux entraînent des frais généraux de performance et sont vraiment excessifs. Pour les flux, le temps système provient de la nécessité de construire le tampon de vapeur et de flux. Pour sprintf, le temps système provient de la nécessité d'interpréter la chaîne de formatage. Cela fonctionne même lorsque n est négatif ou lorsque la représentation sous forme de chaîne de n est plus longue que len . C’est la solution la plus rapide.

inline string some_function(int n, int len)
{
    string result(len--, '0');
    for (int val=(n<0)?-n:n; len>=0&&val!=0; --len,val/=10)
       result[len]='0'+val%10;
    if (len>=0&&n<0) result[0]='-';
    return result;
}

Il y a plusieurs façons de le faire. Le plus simple serait:

int n = 999;
char buffer[256]; sprintf(buffer, "%06d", n);
string str(buffer);

sprintf est la manière de faire cela, semblable à C, qui fonctionne aussi en C ++.

En C ++, combinaison du format de chaîne et du format de sortie du flux (voir http: // www .arachnoid.com / cpptutor / student3.html ) fera le travail.

Ceci est un ancien fil de discussion, mais comme fmt pourrait en devenir un standard, ici est une solution supplémentaire:

#include <fmt/format.h>

int n = 999;

const auto str = fmt::format("{:0>{}}", n, 6);

Notez que le fmt :: format ("{: 0 > 6}", n) fonctionne aussi bien lorsque la largeur souhaitée est connue au moment de la compilation. Une autre option est rappel :

#include <absl/strings/str_format.h>

int n = 999;

const auto str = absl::StrFormat("%0*d", 6, n);

Encore une fois, abs :: StrFormat ("% 06d", n) est possible. Le format de rappel est un autre outil pour résoudre ce problème:

#include <boost/format.hpp>

int n = 999;

const auto str = boost::str(boost::format("%06d") % n);

Malheureusement, les spécificateurs de largeur variable en tant qu'arguments chaînés avec l'opérateur % ne sont pas pris en charge. Ceci nécessite une chaîne de formatage (par exemple, const std :: string fmt = "% 0" + std :: to_string (6) + "d"; ).

En termes de performances, la descente en rappel et le fmt prétendent être très attrayants et plus rapides que le boost. Dans tous les cas, les trois solutions devraient être plus efficaces que les approches std :: stringstream et, mis à part la famille std :: * printf , elles ne sacrifient pas la sécurité de type.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top