I've a little problem with a function that calculates the entire part of the logartihm of an integer. It's a detail in my case but I'd like to understand it ;)
As you see be testing it, my code is just a bubblesort function and my problem is relative to the function called log_entier (because log 9 is here 2 instead of 1, what I don't understand...)
Note that the argument of log_entier is supposed to be > 0
Thanks a lot in advance !!!
Here's my code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void echanger_elements(char *s, unsigned i1, unsigned i2) //echange deux elements d'une chaine dont on donne les indices
{
char element = s[i1];
s[i1] = s[i2];
s[i2] = element;
}
int log_entier(int n)
{
int log = -1;
for (; n; n/=10)
log++;
return log;
}
char *print_digits(char n)
{
char *s;
s = malloc((3 - log_entier(n))*sizeof(char));
int i;
for (i = 3 - log_entier(n); i; i--)
{
s[i - 1] = ' ';
}
return s;
}
void bubblesort(char *s) //trie une chaine de caractères en fonction de l'ordre de la table ascii
{
int i;
char plus_grand_el;
char sorting;
unsigned etape = 1;
unsigned permutations = 0;
while(1)
{
plus_grand_el = 0;
sorting = 0;
for (i = 1; i < strlen(s); i++)
{
if (s[i] < s[plus_grand_el])
{
sorting = 1;
echanger_elements(s, i, plus_grand_el);
permutations++;
}
plus_grand_el++;
}
printf(" Étape %s %d : %s\n", print_digits(etape), etape++, s);
if (sorting == 0)
{
printf(" ***La chaîne a été triée à l'aide de %d!***\n", permutations);
break;
}
}
}
int main()
{
char chaine[] = "ZZTHelXlo56456Wordl1265";
bubblesort(chaine);
}
I would expect something like this :
Étape 1 : ZTHZeXll56456Woodl1265r
Étape 2 : THZZXel56456Wlodl1265or
Étape 3 : HTZXZe56456Wlldl1265oor
Étape 4 : HTXZZ56456Weldl1265loor
Étape 5 : HTXZ56456WZedl1265lloor
Étape 6 : HTX56456WZZde1265llloor
Étape 7 : HT56456WXZZd1265ellloor
Étape 8 : H56456TWXZZ1265dellloor
Étape 9 : 56456HTWXZ1265Zdellloor
Étape 10 : 54566HTWX1265ZZdellloor
Étape 11 : 45566HTW1265XZZdellloor
Étape 12 : 45566HT1265WXZZdellloor
Étape 13 : 45566H1265TWXZZdellloor
Étape 14 : 455661265HTWXZZdellloor
Étape 15 : 455612656HTWXZZdellloor
Étape 16 : 455126566HTWXZZdellloor
Étape 17 : 451255666HTWXZZdellloor
Étape 18 : 412555666HTWXZZdellloor
Étape 19 : 124555666HTWXZZdellloor
Étape 20 : 124555666HTWXZZdellloor
***La chaîne a été triée à l'aide de 142!***
instead of
Étape 1 : ZTHZeXll56456Woodl1265r
Étape 2 : THZZXel56456Wlodl1265or
Étape 3 : HTZXZe56456Wlldl1265oor
Étape 4 : HTXZZ56456Weldl1265loor
Étape 5 : HTXZ56456WZedl1265lloor
Étape 6 : HTX56456WZZde1265llloor
Étape 7 : HT56456WXZZd1265ellloor
Étape 8 : H56456TWXZZ1265dellloor
Étape 9 : 56456HTWXZ1265Zdellloor
Étape 10 : 54566HTWX1265ZZdellloor
Étape 11 : 45566HTW1265XZZdellloor
Étape 12 : 45566HT1265WXZZdellloor
Étape 13 : 45566H1265TWXZZdellloor
Étape 14 : 455661265HTWXZZdellloor
Étape 15 : 455612656HTWXZZdellloor
Étape 16 : 455126566HTWXZZdellloor
Étape 17 : 451255666HTWXZZdellloor
Étape 18 : 412555666HTWXZZdellloor
Étape 19 : 124555666HTWXZZdellloor
Étape 20 : 124555666HTWXZZdellloor
***La chaîne a été triée à l'aide de 142!***
When testing out your program, I noted that the compiler issued a warning about the fact that you were attempting to combine the printing of information and incrementing your "etape" counter together.
/home/craig/C_Programs/Console/Log/main.c|55|warning: operation on ‘etape’ may be undefined [-Wsequence-point]|
This warning referenced your print statement.
printf(" Stage %s %d : %s\n", print_digits(etape), etape++, s);
Usually warnings are indicative of possible undefined behavior. With that, I also experienced the offset of the ninth line in the output.
craig@Vera:~/C_Programs/Console/Log/bin/Release$ ./Log
Stage 1 : ZTHZeXll56456Woodl1265r
Stage 2 : THZZXel56456Wlodl1265or
Stage 3 : HTZXZe56456Wlldl1265oor
Stage 4 : HTXZZ56456Weldl1265loor
Stage 5 : HTXZ56456WZedl1265lloor
Stage 6 : HTX56456WZZde1265llloor
Stage 7 : HT56456WXZZd1265ellloor
Stage 8 : H56456TWXZZ1265dellloor
Stage 9 : 56456HTWXZ1265Zdellloor
Stage 10 : 54566HTWX1265ZZdellloor
Stage 11 : 45566HTW1265XZZdellloor
Stage 12 : 45566HT1265WXZZdellloor
Stage 13 : 45566H1265TWXZZdellloor
Stage 14 : 455661265HTWXZZdellloor
Stage 15 : 455612656HTWXZZdellloor
Stage 16 : 455126566HTWXZZdellloor
Stage 17 : 451255666HTWXZZdellloor
Stage 18 : 412555666HTWXZZdellloor
Stage 19 : 124555666HTWXZZdellloor
Stage 20 : 124555666HTWXZZdellloor
***The string was sorted using 142!***
Determining that what is desired is to print the stage and then increment the variable, following is the refactored code for that purpose.
printf(" Stage %s %d : %s\n", print_digits(etape), etape, s);
etape++;
When compiling this refactored code, the compiler no longer issued a warning about the incrementation of the variable. And following was the resulting test output.
craig@Vera:~/C_Programs/Console/Log/bin/Release$ ./Log
Stage 1 : ZTHZeXll56456Woodl1265r
Stage 2 : THZZXel56456Wlodl1265or
Stage 3 : HTZXZe56456Wlldl1265oor
Stage 4 : HTXZZ56456Weldl1265loor
Stage 5 : HTXZ56456WZedl1265lloor
Stage 6 : HTX56456WZZde1265llloor
Stage 7 : HT56456WXZZd1265ellloor
Stage 8 : H56456TWXZZ1265dellloor
Stage 9 : 56456HTWXZ1265Zdellloor
Stage 10 : 54566HTWX1265ZZdellloor
Stage 11 : 45566HTW1265XZZdellloor
Stage 12 : 45566HT1265WXZZdellloor
Stage 13 : 45566H1265TWXZZdellloor
Stage 14 : 455661265HTWXZZdellloor
Stage 15 : 455612656HTWXZZdellloor
Stage 16 : 455126566HTWXZZdellloor
Stage 17 : 451255666HTWXZZdellloor
Stage 18 : 412555666HTWXZZdellloor
Stage 19 : 124555666HTWXZZdellloor
Stage 20 : 124555666HTWXZZdellloor
***The string was sorted using 142!***
The main takeaway here is to always review your compiler listing for any warnings that might point to undefined behavior. The "C" programming language does allow for combining and compacting operations; however, sometimes it is best to keep steps such as incrementing variables separate (and easier for any future code analysis).
Use that as food for thought.