Подтвердить что ты не робот

Преобразование массива char в число int в C

Я хочу преобразовать массив char [] как:

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

Таким образом, это должно быть целое число: -1234 используя стандартные libaries в C. Я не мог найти элегантный способ сделать это.

Я могу добавить "\ 0" точно.

4b9b3361

Ответ 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, и др.