1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| /* Si ton compilo ne supporte pas long long,
tu peux utiliser un simple long à la place. */
typedef unsigned long long unumber_t;
/* Fonction écrire un nombre comme Excel numérote ses colonnes
-----------------------------------------------------------
Cette fonction écrit le nombre à la fin du buffer,
et retourne un pointeur vers le début du nombre dans le buffer.
C'est plus efficace comme ça. */
char * formatBase26And27(
unumber_t uNumber, /*[in] Nombre à convertir.*/
char * const szBuffer, /*[in/out] Buffer.*/
size_t const nBufferSize, /*[in] Taille du buffer, caractère nul inclus.*/
size_t * const pt_nLength /*[out/opt] taille de la chaîne, sans le caractère nul.*/
) /*Retourne le début du nombre dans le buffer.*/
{
char * pt_currentChar = szBuffer + nBufferSize;
size_t nLength = 0;
/* Premièrement, mettre un caractère nul. */
--pt_currentChar, *pt_currentChar = '\0';
/* Pas de cas spécial pour le premier chiffre ici: Zéro est une chaîne vide. */
while(uNumber != 0)
{
unumber_t uDigit;
char value;
if(uNumber > 26)
{
/*Ce n'est pas la lettre la plus à gauche:
J'ai du mal à décrire ce que je fais ici, je l'ai un peu pondu au hasard.
On compte en base 26 avec A comme zéro,
mais comme en plus on soustrait 1 à chaque fois... */
uNumber--;
uDigit = uNumber % 26;
uNumber /= 26;
value = (char)('A' + uDigit);
}
else
{
/*Lettre la plus à gauche: base 27 pure, avec "rien du tout" comme zéro.*/
uDigit = uNumber;
uNumber = 0;
value = (char)(uDigit!=0
? ('A'+uDigit-1)
: '\0'
);
}
if(value != '\0')
{
--pt_currentChar;
if(pt_currentChar >= szBuffer)
*pt_currentChar = value;
++nLength;
}
}
/* Calcule la longueur. */
if(pt_nLength!=NULL)
{
assert((ptrdiff_t)nLength == (szBuffer+nBufferSize-1) - pt_currentChar);
*pt_nLength = nLength;
}
/* Si on a tronqué, on le marque avec '~' */
if(pt_currentChar < szBuffer)
{
pt_currentChar = szBuffer;
*szBuffer = '~';
}
return pt_currentChar;
}
void TestLettres();
{
char bufferLettres[10];
int i;
#define TESTLETTRES(x) printf("\"%s\" : %u\n", formatBase26And27(x, bufferLettres, 10, NULL), x)
for(i=0 ; i<80 ; i++)
TESTLETTRES(i);
puts(" |");
for(i=26*26-1 ; i<=27*26+1 ; i++)
TESTLETTRES(i);
puts(" |");
TESTLETTRES(((26+1)*26+1)*26);
TESTLETTRES(((26+1)*26+1)*26+1);
puts(" |");
TESTLETTRES((((26+1)*26+1)*26+1)*26);
TESTLETTRES((((26+1)*26+1)*26+1)*26+1);
puts(" |");
TESTLETTRES(((((26+1)*26+1)*26+1)*26+1)*26);
TESTLETTRES(((((26+1)*26+1)*26+1)*26+1)*26+1);
{
unumber_t cumul = 1;
for(i=0 ; i<8 ; i++)
{
TESTLETTRES(cumul);
cumul *= 26;
cumul += 1;
}
}
#undef TESTLETTRES
} |
Partager