Преобразование массива char в число int в C
Я хочу преобразовать массив char [] как:
char myarray[4] = {'-','1','2','3'}; //where the - means it is negative
Таким образом, это должно быть целое число: -1234
используя стандартные libaries в C. Я не мог найти элегантный способ сделать это.
Я могу добавить "\ 0" точно.
Ответы
Ответ 1
Мне лично не нравится функция atoi
. Я бы предложил sscanf
:
char myarray[5] = {'-', '1', '2', '3', '\0'};
int i;
sscanf(myarray, "%d", &i);
Он очень стандартный, он в библиотеке stdio.h
:)
И, на мой взгляд, он позволяет вам гораздо больше свободы, чем atoi
, произвольное форматирование вашей числовой строки и, вероятно, также позволяет использовать нечетные символы в конце.
ИЗМЕНИТЬ
Я просто нашел этот замечательный question здесь, на сайте, который объясняет и сравнивает 3 разных способа сделать это - atoi
, sscanf
и strtol
. Кроме того, имеется более детальное представление о sscanf
(фактически, все семейство функций *scanf
).
EDIT2
Похоже, что не только я лично не люблю функцию atoi
. Вот ссылку , в которой объясняется, что функция atoi
устарела и не должна использоваться в более новом коде.
Ответ 2
Почему бы просто не использовать atoi? Например:
char myarray[4] = {'-','1','2','3'};
int i = atoi(myarray);
printf("%d\n", i);
Дает мне, как и ожидалось:
-123
Обновление: почему бы и нет - массив символов не завершен нулем. Doh!
Ответ 3
Итак, идея состоит в том, чтобы преобразовать номера символов (в одинарных кавычках, например, "8" ) в целочисленное выражение. Например, char c = '8'; int я = c - '0'//даст целое число 8; И суммируем все преобразованные числа по принципу, что 908 = 9 * 100 + 0 * 10 + 8, что делается в цикле.
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
Ответ 4
Не так сложно справиться с массивом символов без преобразования массива в строку. Особенно в том случае, когда длина массива символов известна или может быть легко найдена. С массивом символов длина должна определяться в той же области, что и определение массива, например:
size_t len sizeof myarray/sizeof *myarray;
Для строк вы, конечно, имеете strlen
.
С известной длиной, независимо от того, является ли это символьным массивом или строкой, вы можете преобразовать значения символов в число с короткой функцией, аналогичной следующей:
/* 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;
}
Выше - это просто стандартный подход char to int conversion с несколькими дополнительными условными обозначениями. Чтобы обрабатывать бродячие символы, в дополнение к digits
и '-'
, единственным трюком является выбор умных решений о том, когда начинать сбор цифр и когда остановиться.
Если вы начнете собирать digits
для преобразования, когда вы сталкиваетесь с первым digit
, тогда преобразование завершается, когда вы сталкиваетесь с первым '-'
или non-digit
. Это делает преобразование намного более удобным, если вы заинтересованы в индексах, таких как (например, file_0127.txt
).
Краткий пример его использования:
#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;
}
Примечание., столкнувшись с индексами файлов '-'
с разделителями (или т.п.), вам придется отрицать результат. (например, file-0123.txt
по сравнению с file_0123.txt
, где первая вернет -123
, а вторая 123
).
Результат
$ ./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
Примечание: всегда есть угловые случаи и т.д., которые могут вызвать проблемы. Это не должно быть на 100% пуленепробиваемым во всех наборах символов и т.д., Но вместо этого работать в подавляющем большинстве случаев и обеспечивать дополнительную гибкость преобразования без начального синтаксического анализа или преобразования в строку, требуемую atoi
или strtol
, и др.