web-dev-qa-db-fra.com

Convertit un tableau de caractères en un nombre entier en C

Je veux convertir un tableau de caractères [] comme:

char myarray[4] = {'-','1','2','3'}; //where the - means it is negative

Il devrait donc s'agir du nombre entier: -1234 utilisant standard libaries in C . Je ne trouvais aucun moyen élégant de le faire.

Je peux ajouter le "0" à coup sûr.

29
SpcCode

Personnellement, je n'aime pas la fonction atoi. Je suggérerais sscanf:

char myarray[5] = {'-', '1', '2', '3', '\0'};
int i;
sscanf(myarray, "%d", &i);

C'est très standard, c'est dans le stdio.h bibliothèque :)

Et à mon avis, cela vous laisse beaucoup plus de liberté que atoi, le formatage arbitraire de votre chaîne numérique, et permet probablement aussi des caractères non numériques à la fin.

[~ # ~] modifier [~ # ~] Je viens de trouver ce merveilleux question ici sur le site qui explique et compare 3 façons différentes de le faire - atoi, sscanf et strtol. En outre, il existe un aperçu plus détaillé de Nice sur sscanf (en fait, toute la famille de *scanf les fonctions).

EDIT2 On dirait que ce n'est pas juste moi qui n'aime pas personnellement la fonction atoi. Voici un lien vers une réponse expliquant que la fonction atoi est obsolète et ne devrait pas être utilisée dans du code plus récent.

64
penelope

Pourquoi ne pas simplement utiliser atoi? Par exemple:

char myarray[4] = {'-','1','2','3'};

int i = atoi(myarray);

printf("%d\n", i);

Me donne, comme prévu:

-123

Mise à jour: pourquoi pas - le tableau de caractères n'est pas terminé à zéro. Doh!

7
Rich Drummond

Il n’est pas si difficile de traiter le tableau de caractères lui-même sans convertir le tableau en chaîne. Surtout dans le cas où la longueur du tableau de caractères est connue ou peut être facilement trouvée. Avec le tableau de caractères, la longueur doit être déterminée dans la même portée que la définition du tableau, par exemple:

size_t len sizeof myarray/sizeof *myarray;

Bien entendu, pour les chaînes, vous disposez de strlen.

Avec la longueur connue, qu'il s'agisse d'un tableau de caractères ou d'une chaîne, vous pouvez convertir les valeurs de caractères en un nombre avec une fonction courte similaire à celle-ci:

/* convert character array to integer */
int char2int (char *array, size_t n)
{    
    int number = 0;
    int mult = 1;

    n = (int)n < 0 ? -n : n;       /* quick absolute value check  */

    /* for each character in array */
    while (n--)
    {
        /* if not digit or '-', check if number > 0, break or continue */
        if ((array[n] < '0' || array[n] > '9') && array[n] != '-') {
            if (number)
                break;
            else
                continue;
        }

        if (array[n] == '-') {      /* if '-' if number, negate, break */
            if (number) {
                number = -number;
                break;
            }
        }
        else {                      /* convert digit to numeric value   */
            number += (array[n] - '0') * mult;
            mult *= 10;
        }
    }

    return number;
}

Ci-dessus est simplement l’approche standard de conversion caractère à entier avec quelques conditions additionnelles incluses. Pour gérer les caractères parasites, en plus des caractères digits et '-', le seul truc consiste à faire des choix judicieux pour commencer à collecter des chiffres et arrêter.

Si vous commencez à collecter digits pour la conversion lorsque vous rencontrez le premier digit, la conversion se termine lorsque vous rencontrez le premier '-' ou non-digit. Cela rend la conversion beaucoup plus pratique lorsque des index tels que (par exemple, file_0127.txt).

Un court exemple de son utilisation:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int char2int (char *array, size_t n);

int main (void) {

    char myarray[4] = {'-','1','2','3'}; 
    char *string = "some-goofy-string-with-123-inside";
    char *fname = "file-0123.txt";

    size_t mlen = sizeof myarray/sizeof *myarray;
    size_t slen = strlen (string);
    size_t flen = strlen (fname);

    printf ("\n myarray[4] = {'-','1','2','3'};\n\n");
    printf ("   char2int (myarray, mlen):  %d\n\n", char2int (myarray, mlen));

    printf (" string = \"some-goofy-string-with-123-inside\";\n\n");
    printf ("   char2int (string, slen) :  %d\n\n", char2int (string, slen));

    printf (" fname = \"file-0123.txt\";\n\n");
    printf ("   char2int (fname, flen)  :  %d\n\n", char2int (fname, flen));

    return 0;
}

Note: face à '-' index de fichiers délimités (ou similaires), il vous appartient d’annuler le résultat. (par exemple. file-0123.txt par rapport à file_0123.txt où le premier reviendrait -123 tandis que le second 123).

Exemple de sortie

$ ./bin/atoic_array

 myarray[4] = {'-','1','2','3'};

   char2int (myarray, mlen):  -123

 string = "some-goofy-string-with-123-inside";

   char2int (string, slen) :  -123

 fname = "file-0123.txt";

   char2int (fname, flen)  :  -123

Note: il y a toujours des cas de coin, etc. qui peuvent causer des problèmes. Ceci n'est pas destiné à être à l'épreuve des balles dans tous les jeux de caractères, etc., mais travaille la majorité du temps et offre une flexibilité de conversion supplémentaire sans analyse initiale ni conversion en chaîne requise par atoi ou strtol, etc.

3
David C. Rankin

L’idée est donc de convertir les nombres de caractères (entre guillemets simples, par exemple "8") en expression entière. Par exemple, char c = '8'; int i = c - '0' // donnerait un entier 8; Et résumez tous les nombres convertis par le principe que 908 = 9 * 100 + 0 * 10 + 8, ce qui se fait en boucle.

char t[5] = {'-', '9', '0', '8', '\0'}; //Should be terminated properly.

int s = 1;
int i = -1;
int res = 0;

if (c[0] == '-') {
  s = -1;
  i = 0;
}

while (c[++i] != '\0') { //iterate until the array end
  res = res*10 + (c[i] - '0'); //generating the integer according to read parsed numbers.
}

res = res*s; //answer: -908
2
Otar Magaldadze