Comment convertir un int en une série de caractères

J’essaie de décomposer un entier avec C sur un microcontrôleur 8 bits (un PIC) en ses caractères équivalents ASCII.

Par exemple: convertir 982 en ‘9’, ‘8’, ‘2’

Tout ce que j’ai inventé jusqu’à présent semble être une force assez brutale. C’est l’idée principale de ce que je fais en ce moment:

if( (10 <= n) && (n < 100) ) { // isolate and update the first order of magnitude digit_0 = (n % 10); // isolate and update the second order of magnitude switch( n - (n % 10) ) { case 0: digit_1 = 0; break; case 10: digit_1 = 1; break; 

Et puis j’ai une autre fonction pour simplement append 0b00110000 (48decimal) à chacun de mes chiffres.

J’ai eu du mal à trouver une fonction C pour le faire pour moi ou bien le faire moi-même.

Merci d’avance pour votre aide!

Pour le faire vous-même, vous devez effectuer les opérations illustrées avec l’exemple de code ci-dessous:

 #include  int main (void) { unsigned int x = 512; int base_val = 10, digit, i = 0, n = 0; char x_str[32], t; printf ("\nEnter an unsigned number: "); scanf ("%u", &x); printf ("\nEnter base: "); scanf ("%d", &base_val); /* Chop the digits in reverse order and store in `x_arr` * the interpretation of the digits are made in base value * denoted by `base_val` */ while (x) { digit = x % base_val; x /= base_val; if (digit < 10) x_str[n++] = digit + '0'; else x_str[n++] = digit + 'A' - 10; /* handle base > 9 */ } /* Terminate ssortingng */ x_str[n] = '\0'; /* Reverse ssortingng */ for (i=0; i 

La boucle while coupera les chiffres du nombre entier dans une base donnée et les alimentera en ordre inverse dans un tableau. Le caractère interne if - else gère la base plus de 9 et place les alphabets majuscules lorsqu'une valeur numérique est supérieure à 10. La boucle for inverse la chaîne et obtient le nombre coupé en chaîne dans l'ordre suivant.

Vous devez ajuster la taille du tableau x_str fonction de votre capacité maximale. Définissez une macro pour cela. Notez que le code ci-dessus ne concerne que les entiers non signés. Pour les entiers signés, vous devez d’abord vérifier s’il est inférieur à 0, puis append un signe '-' dans x_str puis imprimer la magnitude c'est-à-dire. applique le code ci-dessus avec -x . Cela peut également être fait en vérifiant le bit de signe, en le masquant, mais en rendant le processus dépendant du stockage de l'entier.

base_val est la base dans laquelle vous voulez interpréter les nombres.

Si sprintf ne convient pas pour une raison quelconque, quelque chose de simple comme ceci fonctionnerait:

 char digits[MAX_DIGITS]; int count = 0; do { digits[count++] = n % 10; n /= 10; } while (n > 0); 

Il y aura un count chiffres, les digits[0] étant les moins significatifs.

J’ai répondu à une question comme celle-ci il y a longtemps.

Mise en œuvre de ftoa

J’espère que ça aide. Cela s’applique aux nombres entiers et aux nombres à virgule flottante. Le concept est simple.

  1. Déterminez le nombre de chiffres (pour la base 10, vous utilisez la firebase database log 10)
  2. Saisissez le nombre en msb en prenant la parole de (num / digit_weight)
  3. Soustrayez chiffre * poids du nombre et diminuez le poids de 1
  4. Recommencez jusqu’au nombre == 0 pour les entiers ou num> 0 + tolérance pour les nombres fp

Comme l’algorithme traite un chiffre à chaque itération, son temps O (logn) est donc raisonnable.

Si vous êtes compatible avec l’assembleur PIC16 RISC, c’est très simple, rapide, court et efficace. Ici, vous avez 16 bits non signés, 16 divisions sur 10, rutines pour voir comment le faire.

Pour obtenir le premier caractère le plus bas du numéro dans WREG, atsortingbuez un numéro non signé de 16 bits à Reg1 et Reg2 et appelez rutine. Pour obtenir le prochain caractère, appelez rutine et ainsi de suite jusqu’à ce que Reg1 et Reg2 deviennent 0.

 RegAE res 1 RegA0 res 1 RegA1 res 1 RegA2 res 1 divR16by_c10 ;{ ;//Input: 16 bit unsigned number as RegA1,2 (RegA2 low byte, RegA1 High byte) ;//Division result: Reg1 and Reg2 and reminder as char in WREG clrf RegA0 movlw 16 ;//init loop counter movwf RegAE lslf RegA2, f divI16by_c10_ rlf RegA1, f rlf RegA0, f movlw 10 subwf RegA0, f btfsc Carry bra divI16by_c10_OK addwfc RegA0, f bcf Carry divI16by_c10_OK rlf RegA2, f decfsz RegAE, f bra divI16by_c10_ ;//result= W from 0..9 addlw 0x30 ;//convert to char return ;} 

MODIFIER:

Si vous souhaitez convertir une valeur signée sur 16 bits, vérifiez d’abord le 15e bit pour déterminer le numéro de signe. Si négatif, écrivez – signez et annulez le nombre dans RegA1,2. Après cela, la procédure est la même pour le nombre positif. Pour annuler un nombre, vous pouvez utiliser l’asm rutine suivant:

  comf RegA2, f comf RegA1, f movlw 0 bsf STATUS, 0 ;//set carry flag addwfc RegA2, f addwfc RegA1, f