Где находится функция itoa в Linux? - PullRequest
129 голосов
/ 10 октября 2008

itoa() - очень удобная функция для преобразования числа в строку. В Linux, похоже, нет itoa(), есть эквивалентная функция или мне нужно использовать sprintf(str, "%d", num)?

Ответы [ 17 ]

91 голосов
/ 10 октября 2008

РЕДАКТИРОВАТЬ: Извините, я должен был помнить, что эта машина явно нестандартная, подключив различные нестандартные реализации libc для академических целей; -)

Поскольку itoa() действительно является нестандартным, как уже упоминалось в нескольких полезных комментариях, лучше использовать sprintf(target_string,"%d",source_int) или (еще лучше, потому что это безопасно от переполнения буфера) snprintf(target_string, size_of_target_string_in_bytes, "%d", source_int). Я знаю, что это не так лаконично или круто, как itoa(), но, по крайней мере, вы можете написать один раз, запустить везде (тм); -)

Вот старый (отредактированный) ответ

Вы правы, утверждая, что gcc libc по умолчанию не включает itoa(), как некоторые другие платформы, поскольку технически он не является частью стандарта. См. здесь для получения дополнительной информации. Обратите внимание, что вы должны

#include <stdlib.h>

Конечно, вы уже знаете это, потому что вы хотели использовать itoa() в Linux после предположительного использования его на другой платформе, но ... код (украденный по ссылке выше) будет выглядеть так :

Пример * +1026 *

/* itoa example */
#include <stdio.h>
#include <stdlib.h>

int main ()
{
  int i;
  char buffer [33];
  printf ("Enter a number: ");
  scanf ("%d",&i);
  itoa (i,buffer,10);
  printf ("decimal: %s\n",buffer);
  itoa (i,buffer,16);
  printf ("hexadecimal: %s\n",buffer);
  itoa (i,buffer,2);
  printf ("binary: %s\n",buffer);
  return 0;
}

Выход:

Enter a number: 1750
decimal: 1750
hexadecimal: 6d6
binary: 11011010110

Надеюсь, это поможет!

12 голосов
/ 10 октября 2008

Если вы часто это называете, совет "просто используйте snprintf" может быть раздражающим. Итак, вот что вы, вероятно, хотите:

const char *my_itoa_buf(char *buf, size_t len, int num)
{
  static char loc_buf[sizeof(int) * CHAR_BITS]; /* not thread safe */

  if (!buf)
  {
    buf = loc_buf;
    len = sizeof(loc_buf);
  }

  if (snprintf(buf, len, "%d", num) == -1)
    return ""; /* or whatever */

  return buf;
}

const char *my_itoa(int num)
{ return my_itoa_buf(NULL, 0, num); }
10 голосов
/ 09 апреля 2015

itoa не является стандартной функцией C. Вы можете реализовать свой собственный. Оно появилось в первом издании Кернигана и Ритчи Язык программирования C , на странице 60. Второе издание языка программирования C ("K & R2") содержит следующую реализацию itoa на странице 64. В книге отмечены некоторые проблемы с этой реализацией, в том числе тот факт, что неправильно обрабатывает наиболее отрицательное число

 /* itoa:  convert n to characters in s */
 void itoa(int n, char s[])
 {
     int i, sign;

     if ((sign = n) < 0)  /* record sign */
         n = -n;          /* make n positive */
     i = 0;
     do {       /* generate digits in reverse order */
         s[i++] = n % 10 + '0';   /* get next digit */
     } while ((n /= 10) > 0);     /* delete it */
     if (sign < 0)
         s[i++] = '-';
     s[i] = '\0';
     reverse(s);
}  

Функция reverse, использованная выше, реализована двумя страницами ранее:

 #include <string.h>

 /* reverse:  reverse string s in place */
 void reverse(char s[])
 {
     int i, j;
     char c;

     for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
         c = s[i];
         s[i] = s[j];
         s[j] = c;
     }
}  
6 голосов
/ 10 октября 2008

Как писал Мэтт Дж, есть itoa, но это не стандартно. Ваш код будет более переносимым, если вы используете snprintf.

6 голосов
/ 15 ноября 2012

Редактировать: Я только что узнал о std::to_string, который по работе идентичен моей собственной функции ниже. Он был представлен в C ++ 11 и доступен в последних версиях gcc, по крайней мере, еще в 4.5, если вы включите расширения c ++ 0x.


Мало того, что itoa отсутствует в gcc, это не самая удобная функция для использования, так как вам нужно передать ее в буфер. Мне нужно было что-то, что можно было бы использовать в выражении, поэтому я придумал это:
std::string itos(int n)
{
   const int max_size = std::numeric_limits<int>::digits10 + 1 /*sign*/ + 1 /*0-terminator*/;
   char buffer[max_size] = {0};
   sprintf(buffer, "%d", n);
   return std::string(buffer);
}

Обычно было бы безопаснее использовать snprintf вместо sprintf, но размер буфера был тщательно подобран, чтобы не зависеть от переполнения.

См. Пример: http://ideone.com/mKmZVE

4 голосов
/ 13 ноября 2012

Следующая функция выделяет достаточно памяти для хранения строкового представления заданного числа, а затем записывает строковое представление в эту область, используя стандартный метод sprintf.

char *itoa(long n)
{
    int len = n==0 ? 1 : floor(log10l(labs(n)))+1;
    if (n<0) len++; // room for negative sign '-'

    char    *buf = calloc(sizeof(char), len+1); // +1 for null
    snprintf(buf, len+1, "%ld", n);
    return   buf;
}

Не забудьте free увеличить выделенную память при необходимости:

char *num_str = itoa(123456789L);
// ... 
free(num_str);

N.B. Поскольку snprintf копирует n-1 байт, мы должны вызвать snprintf (buf, len + 1, "% ld", n) (а не просто snprintf (buf, len, "% ld", n))

2 голосов
/ 13 октября 2017

Где находится функция itoa в Linux?

В Linux такой функции нет. Вместо этого я использую этот код.

/*
=============
itoa

Convert integer to string

PARAMS:
- value     A 64-bit number to convert
- str       Destination buffer; should be 66 characters long for radix2, 24 - radix8, 22 - radix10, 18 - radix16.
- radix     Radix must be in range -36 .. 36. Negative values used for signed numbers.
=============
*/

char* itoa (unsigned long long  value,  char str[],  int radix)
{
    char        buf [66];
    char*       dest = buf + sizeof(buf);
    boolean     sign = false;

    if (value == 0) {
        memcpy (str, "0", 2);
        return str;
    }

    if (radix < 0) {
        radix = -radix;
        if ( (long long) value < 0) {
            value = -value;
            sign = true;
        }
    }

    *--dest = '\0';

    switch (radix)
    {
    case 16:
        while (value) {
            * --dest = '0' + (value & 0xF);
            if (*dest > '9') *dest += 'A' - '9' - 1;
            value >>= 4;
        }
        break;
    case 10:
        while (value) {
            *--dest = '0' + (value % 10);
            value /= 10;
        }
        break;

    case 8:
        while (value) {
            *--dest = '0' + (value & 7);
            value >>= 3;
        }
        break;

    case 2:
        while (value) {
            *--dest = '0' + (value & 1);
            value >>= 1;
        }
        break;

    default:            // The slow version, but universal
        while (value) {
            *--dest = '0' + (value % radix);
            if (*dest > '9') *dest += 'A' - '9' - 1;
            value /= radix;
        }
        break;
    }

    if (sign) *--dest = '-';

    memcpy (str, dest, buf +sizeof(buf) - dest);
    return str;
}
1 голос
/ 19 апреля 2013

Я попробовал собственную реализацию itoa (), похоже, работает в двоичном, восьмеричном, десятичном и шестнадцатеричном виде

#define INT_LEN (10)
#define HEX_LEN (8)
#define BIN_LEN (32)
#define OCT_LEN (11)

static char *  my_itoa ( int value, char * str, int base )
{
    int i,n =2,tmp;
    char buf[BIN_LEN+1];


    switch(base)
    {
        case 16:
            for(i = 0;i<HEX_LEN;++i)
            {
                if(value/base>0)
                {
                    n++;
                }
            }
            snprintf(str, n, "%x" ,value);
            break;
        case 10:
            for(i = 0;i<INT_LEN;++i)
            {
                if(value/base>0)
                {
                    n++;
                }
            }
            snprintf(str, n, "%d" ,value);
            break;
        case 8:
            for(i = 0;i<OCT_LEN;++i)
            {
                if(value/base>0)
                {
                    n++;
                }
            }
            snprintf(str, n, "%o" ,value);
            break;
        case 2:
            for(i = 0,tmp = value;i<BIN_LEN;++i)
            {
                if(tmp/base>0)
                {
                    n++;
                }
                tmp/=base;
            }
            for(i = 1 ,tmp = value; i<n;++i)
            {
                if(tmp%2 != 0)
                {
                    buf[n-i-1] ='1';
                }
                else
                {
                    buf[n-i-1] ='0';
                }
                tmp/=base;
            }
            buf[n-1] = '\0';
            strcpy(str,buf);
            break;
        default:
            return NULL;
    }
    return str;
}
1 голос
/ 18 января 2013

прямое копирование в буфер: 64-битное целое число, шестнадцатеричное в itoa:

    char* itoah(long num, char* s, int len)
    {
            long n, m = 16;
            int i = 16+2;
            int shift = 'a'- ('9'+1);


            if(!s || len < 1)
                    return 0;

            n = num < 0 ? -1 : 1;
            n = n * num;

            len = len > i ? i : len;
            i = len < i ? len : i;

            s[i-1] = 0;
            i--;

            if(!num)
            {
                    if(len < 2)
                            return &s[i];

                    s[i-1]='0';
                    return &s[i-1];
            }

            while(i && n)
            {
                    s[i-1] = n % m + '0';

                    if (s[i-1] > '9')
                            s[i-1] += shift ;

                    n = n/m;
                    i--;
            }

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

            return &s[i];
    }

примечание: измените длинную на длинную длинную для 32-битной машины. long для int в случае 32-разрядного целого числа. м это основа. При уменьшении радиуса увеличьте количество символов (переменная i). При увеличении радиуса уменьшайте количество символов (лучше). В случае неподписанного типа данных, я просто становлюсь 16 + 1.

1 голос
/ 16 января 2014

Если вы просто хотите распечатать их:

void binary(unsigned int n)
{
    for(int shift=sizeof(int)*8-1;shift>=0;shift--)
    {
       if (n >> shift & 1)
         printf("1");
       else
         printf("0");

    }
    printf("\n");
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...