OVH Cloud OVH Cloud

Convertir un nombre en lettres

14 réponses
Avatar
Michael
Bonjour à tous,

je voudrais convertir un index de colonne depuis un int vers une chaine.

Toujours pour ma classe Excel, je voudrais obtenir 'A' depuis 1, 'AB'
depuis 28 par exemple.

J'ai trouvé la fonction suivante sur le net:

AnsiString XLCells::Get_Indice_Colonne(int colonne)
{
int diviseur;
int reste;
AnsiString indice;
char carac;

do
{
diviseur = colonne / 26;
reste = colonne % 26;

// Conversion en caractère
carac = reste + 64; // Code Ascii du A = 65

indice += carac;

colonne = diviseur;
}
while (diviseur != 0);

//Les lettres de la colonne sont inversés, donc on remet dans l'ordre
AnsiString chaine;
for(int i = indice.Length(); i > 0; i--)
chaine += indice.SubString(i, 1);

return chaine;
}

Problème: dès qu'il y a un 'Z' dans le retour ça ne marche plus, j'ai
'@'.

Comment je peux résoudre ça?

Merci d'avance

4 réponses

1 2
Avatar
kanze
Jean-Marc Bourguet wrote:

ainsi le jour ou on decide que O et I risquent d'etre
confondus avec 0 et 1 et doivent donc etre evites, on n'a
qu'une chose a faire.


En passant, il est courant en Allemagne de ne pas distinguer
entre le I et le J. Au fond, l'ensemble de caractères utilisé
(et donc la base) doit dépendre du locale:-).

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Jean-Marc Bourguet
writes:

Tu l'as essayé pour le colonne 27 ?


Non. J'en suis confu. :-)

Je me retrouve avec quelque chose comme :

std::string
getColumnDisplayRepresentation( int column, int width = 2 )
{
static char const digits[]
= " ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
int const base = sizeof( digits ) - 2 ;
std::string result ;
-- column ;
do {
result.push_back( digits[ column % base + 1 ] ) ;
column /= base ;
} while ( column > base ) ;
if ( column != 0 ) {
result.push_back( digits[ column ] ) ;
}
if ( result.size() < width ) {
result.resize( width, digits[ 0 ] ) ;
}
std::reverse( result.begin(), result.end() ) ;
return result ;
}


Tu l'as essayé pour les colonnes 26+26*26, 27+26*26,
26+26*26+26*26*26, 27+26*26+26*26*26 ? :-)

J'en arrive à:

std::string getColumnDisplayRepresentation(int column)
{
assert(column > 0);

static char digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static int const base = sizeof(digits) - 1;
static int const maxResultSize = sizeof(column)*CHAR_BIT+1;

char result[maxResultSize];
int index = maxResultSize;

result[--index] = '';
do {
--column;
result[--index] = digits[column % base];
column /= base;
} while (column != 0);

return result+index;
}

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
kanze
Jean-Marc Bourguet wrote:
writes:

Tu l'as essayé pour le colonne 27 ?


Non. J'en suis confu. :-)

Je me retrouve avec quelque chose comme :

std::string
getColumnDisplayRepresentation( int column, int width = 2 )
{
static char const digits[]
= " ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
int const base = sizeof( digits ) - 2 ;
std::string result ;
-- column ;
do {
result.push_back( digits[ column % base + 1 ] ) ;
column /= base ;
} while ( column > base ) ;
if ( column != 0 ) {
result.push_back( digits[ column ] ) ;
}
if ( result.size() < width ) {
result.resize( width, digits[ 0 ] ) ;
}
std::reverse( result.begin(), result.end() ) ;
return result ;
}


Tu l'as essayé pour les colonnes 26+26*26, 27+26*26,
26+26*26+26*26*26, 27+26*26+26*26*26 ? :-)


En effet. Je me suis arrêté à deux caractères dans mes tests.

J'en arrive à:

std::string getColumnDisplayRepresentation(int column)
{
assert(column > 0);

static char digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static int const base = sizeof(digits) - 1;
static int const maxResultSize = sizeof(column)*CHAR_BIT+1;

char result[maxResultSize];
int index = maxResultSize;

result[--index] = '';
do {
--column;
result[--index] = digits[column % base];
column /= base;
} while (column != 0);

return result+index;
}


Tout à fait. En fait, c'est beaucoup plus simple que je ne
croyais ; c'est réelement du base 26, mais avec chaque chiffre
incrémenté avant d'y être ajouté. Ou quelque chose comme ça.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Jean-Marc Bourguet
writes:

Tout à fait. En fait, c'est beaucoup plus simple que je ne
croyais ; c'est réelement du base 26, mais avec chaque chiffre
incrémenté avant d'y être ajouté. Ou quelque chose comme ça.


La valeur est sum_i d_i b^i mais les chiffres vont de 1 a b plutot
que de 0 a b-1 comme d'habitude.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

1 2