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.
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.
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!
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.
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