লিনাক্সে ইতোয়া ফাংশনটি কোথায়?


139

itoa()একটি সংখ্যাকে একটি স্ট্রিংয়ে রূপান্তর করার জন্য একটি সত্যই কার্যকর কাজ। লিনাক্স আছে বলে মনে হয় না itoa(), এর কোন সমতুল্য ফাংশন আছে বা আমার ব্যবহার করতে হবে sprintf(str, "%d", num)?


4
কোন কারণে ব্যবহার না sprintf(str, "%d", num)? এটা তুলনায় অনেক ধীর itoa?
javapowered

1
@ জাভাপাওয়ার্ড, একের জন্য itoaনির্বিচার বেস ভিত্তিক রূপান্তরকে অনুমতি দেয়, printfনির্দিষ্টকারীরা তা করে না।
ভ্লাদর

@ জাভাপাওয়ার্ড স্প্রিন্টফ () নিরাপদ সিগন্যাল নয়
লুনেসকো

gcvt()স্ট্যান্ডার্ড লাইব্রেরি থেকে ব্যবহার না করার কোনও কারণ ?
সুবিন সেবাস্তিয়ান

উত্তর:


100

সম্পাদনা: দুঃখিত, আমার মনে রাখা উচিত ছিল যে এই মেশিনটি সিদ্ধান্তগতভাবে অ-মানক, 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() করার পরে লিনাক্সে ব্যবহার করতে চেয়েছিলেন , কিন্তু ... কোডটি (উপরের লিঙ্কটি থেকে চুরি হয়েছে) দেখতে দেখতে এই রকম হবে:

উদাহরণ

/* 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

আশাকরি এটা সাহায্য করবে!


1
হুম, সংকলন করে দেবিয়ান আমাকে আমাকে "`তোয়া" এর অপরিবর্তিত রেফারেন্স দেয় "। আমার সিস্টেমে কিছু ভুল হতে পারে।
অ্যাডাম পিয়ার্স

আমি উবুন্টু 8.04 এ একই পাই। Stdio.h বা stdlib.h এ আমি আইটোয়ার কোনও রেফারেন্স পাই না (আশ্চর্যজনক যেহেতু এটি স্ট্যান্ডার্ডের অংশ নয়)
ক্যাম এ

শুদ্ধতার জন্য সম্পাদিত, ধন্যবাদ ছেলেরা! দুঃখিত, আমি সর্বদা ভুলে যাই যে এটি কোনও ভ্যানিলা লিনাক্স বক্স নয় ;-)
ম্যাট জে

বাফার সাইজের যুক্তিটি অন্তর্ভুক্ত করার জন্য আমি উত্তরটি সম্পাদনা করেছি; আমি বিশ্বাস করি সবকিছু এখনকার মতো ঠিক আছে, আমি প্রতি সেয়ে যুক্তির ক্রম নিয়ে কোনও সমস্যা দেখছি না। আমি কিছু অনুপস্থিত করছি?
ম্যাট জে

এটি লিনাক্সের জন্য কাজ করে না? প্রশ্ন / উত্তরের ফলাফল কী (অ-মানকটি সমস্ত লিনাক্স বলে মনে হচ্ছে?)

12

আপনি যদি এটিকে অনেক কিছু বলছেন, তবে "স্নাপ্রিন্টফ ব্যবহার করুন" এর পরামর্শ বিরক্তিকর হতে পারে। সুতরাং আপনি সম্ভবত যা চান তা এখানে:

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); }

8
মতামত মত বলেছেন :)
জেমস অ্যান্টিল

17
এটি কেবল নন-থ্রেড নিরাপদ নয়, এটি একেবারেই নিরাপদ নয়: - শূন্য কিছু_ফানক (চর * এ, চর * বি); some_func (itoa (123), itoa (456)); ফাংশনটি কী গ্রহণ করে তা অনুমান করার জন্য যত্নশীল?
jcoder

এছাড়াও, constকোয়ালিফায়াররা ফাংশন রিটার্নের ধরণগুলিতে কিছুই করেনা - আপনি যদি সংকলক সতর্কতাগুলি চালু করেন তবে আপনি এটি জানতেন :)
বিড়াল

3
@ ক্যাট তবে এখানে কোনও কনস্ট-কোয়ালিফাইড রিটার্নের ধরণ নেই। const char *কনস্টের প্রতি নিরপেক্ষ পয়েন্টার, যা প্রচুর পরিমাণে বোঝায় এবং সঠিক।
Chortos-2

1
@ Chortos-2 এটি আকর্ষণীয়, আপনি অবশ্যই অবশ্যই সম্পূর্ণ সঠিক - আমি এবং এর constমধ্যকার অর্থের অর্থগত পার্থক্যটি বুঝতে পারি নি , তবে এখন এটি একটি সংকলক দিয়ে চেষ্টা করে দেখলে তা বোঝা যায়। const int f (void) { ...const int* f (void) { ...
বিড়াল

11

itoaকোনও স্ট্যান্ডার্ড সি ফাংশন নয়। আপনি নিজের প্রয়োগ করতে পারেন। এটি কার্নিগান এবং রিচির দ্য সি প্রোগ্রামিং ল্যাঙ্গুয়েজের প্রথম সংস্করণে page০ পৃষ্ঠায় প্রকাশিত হয়েছিল। দ্য সি প্রোগ্রামিং ল্যাঙ্গুয়েজের দ্বিতীয় সংস্করণে ("কে ও আর 2") itoaপৃষ্ঠায় on৪-এর নিম্নলিখিত প্রয়োগ রয়েছে The বইটি এই বাস্তবায়নের সাথে বেশ কয়েকটি বিষয় উল্লেখ করেছে এটি সর্বাধিক নেতিবাচক সংখ্যাকে সঠিকভাবে পরিচালনা করে না এমনটি সহ

 /* 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;
     }
}  

8

সম্পাদনা করুন: আমি কেবলমাত্র std::to_stringনীচে আমার নিজের ক্রিয়াকলাপে অপারেশনের সাথে সাদৃশ্যপূর্ণ এটি সম্পর্কে সন্ধান করেছি। এটি সি ++ 11 এ প্রবর্তিত হয়েছিল এবং আপনি সি ++ 0 এক্স এক্সটেনশানগুলি সক্ষম করলে কমপক্ষে 4.5 হিসাবে প্রাথমিকভাবে জিসিসির সাম্প্রতিক সংস্করণগুলিতে উপলব্ধ।


কেবল itoaজিসিসি থেকে নিখোঁজই নয়, এটি আপনাকে সবচেয়ে বাফার খাওয়ানোর প্রয়োজন হওয়ায় এটি হ্যান্ডিস্ট ফাংশনটি নয়। আমার এমন কিছু প্রয়োজন ছিল যা একটি অভিব্যক্তি হিসাবে ব্যবহার করা যেতে পারে তাই আমি এটি নিয়ে এসেছি:

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


12
প্রশ্নটি সি সম্পর্কে বলে মনে হচ্ছে, যার কোনও std::স্টাফ নেই
glglgl

6

ম্যাট জে যেমন লিখেছেন, আছে itoa, তবে এটি মানক নয়। আপনি যদি ব্যবহার করেন তবে আপনার কোডটি আরও পোর্টেবল হবে snprintf


4

নিম্নলিখিত ফাংশন প্রদত্ত সংখ্যার স্ট্রিং উপস্থাপনা রাখতে পর্যাপ্ত পরিমাণ মেমরি বরাদ্দ করে এবং তারপরে স্ট্যান্ডার্ড 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);

এনবি যেমন স্নিপ্রিন্টফ এন -1 বাইট অনুলিপি করে, আমাদের স্নিপ্রিন্টফ (বুফ, লেন + 1, "% এলডি", এন) কল করতে হবে (কেবল স্নিপ্রিন্টফ নয় (বুফ, লেন, "% এলডি", এন))


4
আপনার ফাংশনটি কল করা ভাল ধারণা নয় itoaতবে সাধারণ প্রয়োগগুলি itoaআসলে কী তা ভিন্ন আচরণ দেয় give এই ফাংশনটি একটি ঠিক ধারণা, তবে এটিকে অন্য কোনও কল করুন :) আমিও snprintfভাসমান পয়েন্টের স্ট্রিংয়ের পরিবর্তে বাফার দৈর্ঘ্য গণনা করার জন্য ব্যবহার করার পরামর্শ দেব ; ভাসমান পয়েন্টে কর্নার কেস ভুল হতে পারে। এবং কলোক কাস্ট করবেন না
এমএম

পরামর্শের জন্য ধন্যবাদ।
মিমডিমিরবাস

এটি labsযদি দীর্ঘ পূর্ণসংখ্যার কাজ করে তবে এটি ব্যবহার করা উচিত । অন্যথায় এটি কেটে যেতে পারে।
Schwern

snprintfchar buf[64]দৈর্ঘ্য পেতে চাইলে একটি নির্দিষ্ট আকারের ট্যাম্প বাফার করুন mallocএবং তারপরে অনুলিপি করুন। তুমি বাইরে কোন সুবিধার পেয়ে থাকেন callocবেশি malloc, যেহেতু আপনি সব বাইট লিখুন। খুব সংক্ষিপ্ত স্ট্রিংয়ের অতিরিক্ত অনুলিপি ভাসমান পয়েন্ট লগ 10 কল করার চেয়ে কম খারাপ। একটি পূর্ণসংখ্যার লগ 2 সহ একটি দ্রুত সান্নিধ্য কার্যকর হতে পারে, যদিও আপনার যদি একটি বিট-স্ক্যান ফাংশন থাকে যা নির্ভরযোগ্যভাবে দক্ষ কোনও জিনিসে (যেমন bsrx86 এর মতো ) ইনলাইন করবে । (বিকল্প: mallocএকটি 64 বাইট বাফার এবং তারপরে reallocআপনি চূড়ান্ত দৈর্ঘ্যটি জানবেন))
পিটার

3

লিনাক্সে ইতোয়া ফাংশনটি কোথায়?

লিনাক্সে এ জাতীয় কোনও ফাংশন নেই। পরিবর্তে আমি এই কোডটি ব্যবহার করি।

/*
=============
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;
}

এই কোডটি প্রশ্নের উত্তর কীভাবে দেয় তা বোঝাতে আপনার উত্তরটি সম্পাদনা করা উচিত।
সি হেলিং

2

আমি ইটোয়া () এর নিজস্ব প্রয়োগের চেষ্টা করেছি, মনে হচ্ছে এটি বাইনারি, অক্টাল, দশমিক এবং হেক্সে কাজ করেছে

#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

বাফারে সরাসরি অনুলিপি করুন: bit৪ বিট ইন্টিজার ইতোয়া হেক্স:

    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 বিট মেশিনের জন্য দীর্ঘ থেকে দীর্ঘ দীর্ঘ পরিবর্তন করুন। 32 বিট পূর্ণসংখ্যার ক্ষেত্রে দীর্ঘ থেকে আন্তঃ মিডিক্স হল মি। রেডিক্স হ্রাস করার সময়, অক্ষরের সংখ্যা বৃদ্ধি করুন (ভেরিয়েবল i)। র‌্যাডিক্স বাড়ানোর সময়, অক্ষরের সংখ্যা হ্রাস করুন (আরও ভাল)। স্বাক্ষরযুক্ত ডেটা প্রকারের ক্ষেত্রে, আমি কেবল 16 + 1 হয়ে যাই।


1

অর্চনা এর সমাধানের অনেক উন্নত সংস্করণ এখানে। এটি কোনও র‌ডিক্স 1-16, এবং সংখ্যার <= 0 এর জন্য কাজ করে এবং এটি ক্লোবার মেমরির উচিত নয়।

static char _numberSystem[] = "0123456789ABCDEF";
static char _twosComp[] = "FEDCBA9876543210";

static void safestrrev(char *buffer, const int bufferSize, const int strlen)
{
    int len = strlen;
    if (len > bufferSize)
    {
        len = bufferSize;
    }
    for (int index = 0; index < (len / 2); index++)
    {
        char ch = buffer[index];
        buffer[index] = buffer[len - index - 1];
        buffer[len - index - 1] = ch;
    }
}

static int negateBuffer(char *buffer, const int bufferSize, const int strlen, const int radix)
{
    int len = strlen;
    if (len > bufferSize)
    {
        len = bufferSize;
    }
    if (radix == 10)
    {
        if (len < (bufferSize - 1))
        {
            buffer[len++] = '-';
            buffer[len] = '\0';
        }
    }
    else
    {
        int twosCompIndex = 0;
        for (int index = 0; index < len; index++)
        {
            if ((buffer[index] >= '0') && (buffer[index] <= '9'))
            {
                twosCompIndex = buffer[index] - '0';
            }
            else if ((buffer[index] >= 'A') && (buffer[index] <= 'F'))
            {
                twosCompIndex = buffer[index] - 'A' + 10;
            }
            else if ((buffer[index] >= 'a') && (buffer[index] <= 'f'))
            {
                twosCompIndex = buffer[index] - 'a' + 10;
            }
            twosCompIndex += (16 - radix);
            buffer[index] = _twosComp[twosCompIndex];
        }
        if (len < (bufferSize - 1))
        {
            buffer[len++] = _numberSystem[radix - 1];
            buffer[len] = 0;
        }
    }
    return len;
}

static int twosNegation(const int x, const int radix)
{
    int n = x;
    if (x < 0)
    {
        if (radix == 10)
        {
            n = -x;
        }
        else
        {
            n = ~x;
        }
    }
    return n;
}

static char *safeitoa(const int x, char *buffer, const int bufferSize, const int radix)
{
    int strlen = 0;
    int n = twosNegation(x, radix);
    int nuberSystemIndex = 0;

    if (radix <= 16)
    {
        do
        {
            if (strlen < (bufferSize - 1))
            {
                nuberSystemIndex = (n % radix);
                buffer[strlen++] = _numberSystem[nuberSystemIndex];
                buffer[strlen] = '\0';
                n = n / radix;
            }
            else
            {
                break;
            }
        } while (n != 0);
        if (x < 0)
        {
            strlen = negateBuffer(buffer, bufferSize, strlen, radix);
        }
        safestrrev(buffer, bufferSize, strlen);
        return buffer;
    }
    return NULL;
}

1

আপনি যদি কেবল এগুলি মুদ্রণ করতে চান:

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");
} 

1

জীবিকার জন্য এটি করে এমন ছেলের কোডটি পড়লে আপনি লম্বা উপায় পাবেন।

মাইএসকিউএল থেকে আসা ছেলেরা কীভাবে এটি করেছে তা দেখুন। উত্সটি হ'ল ওয়েল কমেন্টেড এবং পুরো জায়গা জুড়ে পাওয়া হ্যাক আপ সমাধানের চেয়ে আরও অনেক কিছু শিখিয়ে দেবে।

মাইএসকিউএল এর ইনট 2 টির বাস্তবায়ন

আমি এখানে উল্লিখিত বাস্তবায়ন সরবরাহ করি; লিঙ্কটি এখানে রেফারেন্সের জন্য রয়েছে এবং সম্পূর্ণ প্রয়োগটি পড়তে ব্যবহার করা উচিত।

char *
int2str(long int val, char *dst, int radix, 
        int upcase)
{
  char buffer[65];
  char *p;
  long int new_val;
  char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower;
  ulong uval= (ulong) val;

  if (radix < 0)
  {
    if (radix < -36 || radix > -2)
      return NullS;
    if (val < 0)
    {
      *dst++ = '-';
      /* Avoid integer overflow in (-val) for LLONG_MIN (BUG#31799). */
      uval = (ulong)0 - uval;
    }
    radix = -radix;
  }
  else if (radix > 36 || radix < 2)
    return NullS;

  /*
    The slightly contorted code which follows is due to the fact that
    few machines directly support unsigned long / and %.  Certainly
    the VAX C compiler generates a subroutine call.  In the interests
    of efficiency (hollow laugh) I let this happen for the first digit
    only; after that "val" will be in range so that signed integer
    division will do.  Sorry 'bout that.  CHECK THE CODE PRODUCED BY
    YOUR C COMPILER.  The first % and / should be unsigned, the second
    % and / signed, but C compilers tend to be extraordinarily
    sensitive to minor details of style.  This works on a VAX, that's
    all I claim for it.
  */
  p = &buffer[sizeof(buffer)-1];
  *p = '\0';
  new_val= uval / (ulong) radix;
  *--p = dig_vec[(uchar) (uval- (ulong) new_val*(ulong) radix)];
  val = new_val;
  while (val != 0)
  {
    ldiv_t res;
    res=ldiv(val,radix);
    *--p = dig_vec[res.rem];
    val= res.quot;
  }
  while ((*dst++ = *p++) != 0) ;
  return dst-1;
}

1
একটি সম্ভাব্য সমাধান একটি লিঙ্ক সবসময় স্বাগত জানাই, কিন্তু দয়া করে লিংক প্রায় প্রসঙ্গ যোগ যাতে আপনার সহ-ব্যবহারকারীদের কিছু ধারণা কি এটা থাকবে এবং কেন এটা আছে। টার্গেট সাইটটি যদি অ্যাক্সেসযোগ্য না হয় বা স্থায়ীভাবে অফলাইনে চলে যায় তবে সর্বদা গুরুত্বপূর্ণ লিঙ্কের সর্বাধিক প্রাসঙ্গিক অংশটি উদ্ধৃত করুন। বিবেচনায় রাখুন যে কোনও বাহ্যিক সাইটের লিঙ্কের চেয়ে সবেমাত্র বেশি হওয়া একটি সম্ভাব্য কারণ কেন এবং কীভাবে কিছু উত্তর মুছে ফেলা হয়?
টুনাকি

1
আপনি এখানে পোস্ট করা স্নিপেট সম্পর্কে এত ভাল কি? ভবিষ্যতের পাঠকদের কী সন্ধান করা উচিত?
মার্টিজন পিটারস

1

লিনাক্সে ইতোয়া ফাংশনটি কোথায়?

হিসাবে itoa()সি মান নয়, বিভিন্ন ফাংশন স্বাক্ষর সঙ্গে বিভিন্ন সংস্করণ বিদ্যমান।
char *itoa(int value, char *str, int base);* নিক্সে সাধারণ।

এটি লিনাক্স থেকে হারিয়ে যাওয়া বা কোড বহনযোগ্যতা সীমাবদ্ধ করতে না চাইলে কোড এটিকে নিজস্ব করতে পারে।

নীচে এমন সংস্করণ দেওয়া আছে যা INT_MINসমস্যা বাফারগুলির সাথে সমস্যা না করে এবং পরিচালনা করে: NULLবা অপর্যাপ্ত বাফার রিটার্ন দেয় NULL

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

// Buffer sized for a decimal string of a `signed int`, 28/93 > log10(2)
#define SIGNED_PRINT_SIZE(object)  ((sizeof(object) * CHAR_BIT - 1)* 28 / 93 + 3)

char *itoa_x(int number, char *dest, size_t dest_size) {
  if (dest == NULL) {
    return NULL;
  }

  char buf[SIGNED_PRINT_SIZE(number)];
  char *p = &buf[sizeof buf - 1];

  // Work with negative absolute value
  int neg_num = number < 0 ? number : -number;

  // Form string
  *p = '\0';
  do {
    *--p = (char) ('0' - neg_num % 10);
    neg_num /= 10;
  } while (neg_num);
  if (number < 0) {
    *--p = '-';
  }

  // Copy string
  size_t src_size = (size_t) (&buf[sizeof buf] - p);
  if (src_size > dest_size) {
    // Not enough room
    return NULL;
  }
  return memcpy(dest, p, src_size);
}

নীচে একটি সি 99 বা পরবর্তী সংস্করণ রয়েছে যা কোনও বেসকে পরিচালনা করে [2 ... 36]

char *itoa_x(int number, char *dest, size_t dest_size, int base) {
  if (dest == NULL || base < 2 || base > 36) {
    return NULL;
  }

  char buf[sizeof number * CHAR_BIT + 2]; // worst case: itoa(INT_MIN,,,2)
  char *p = &buf[sizeof buf - 1];

  // Work with negative absolute value to avoid UB of `abs(INT_MIN)`
  int neg_num = number < 0 ? number : -number;

  // Form string
  *p = '\0';
  do {
    *--p = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-(neg_num % base)];
    neg_num /= base;
  } while (neg_num);
  if (number < 0) {
    *--p = '-';
  }

  // Copy string
  size_t src_size = (size_t) (&buf[sizeof buf] - p);
  if (src_size > dest_size) {
    // Not enough room
    return NULL;
  }
  return memcpy(dest, p, src_size);
}

একটি C89 এবং সামনের কোড অনুসারে, অভ্যন্তরীণ লুপটি এর সাথে প্রতিস্থাপন করুন

  div_t qr;
  do {
    qr = div(neg_num, base);
    *--p = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-qr.rem];
    neg_num = qr.quot;
  } while (neg_num);

1

glibc অভ্যন্তরীণ বাস্তবায়ন

glibc 2.28 এর অভ্যন্তরীণ বাস্তবায়ন রয়েছে:

যা অভ্যন্তরীণভাবে বেশ কয়েকটি স্থানে ব্যবহৃত হয়, তবে এটি উন্মুক্ত বা কীভাবে হবে তা আমি খুঁজে পেলাম না।

অন্তত এটির একটি দৃ implementation় বাস্তবায়ন হওয়া উচিত যদি আপনি এটিকে উত্তোলন করতে চান।

এই প্রশ্নটি জিজ্ঞাসা করে যে কীভাবে আপনার নিজের রোল করবেন: কীভাবে একটি ইনটাকে সি তে রূপান্তর করবেন?


1

আমি এটি পছন্দ করতে চাই: https://github.com/wsq003/itoa_for_linux

এটি এখন পর্যন্ত সবচেয়ে দ্রুততম আইটোয়া হওয়া উচিত। পারফরম্যান্সের কারণে আমরা স্প্রিন্টফ () এর পরিবর্তে ইটোোয়া () ব্যবহার করি, সুতরাং সীমিত বৈশিষ্ট্যযুক্ত একটি দ্রুততম আইটোয়া () যুক্তিসঙ্গত এবং সার্থক।


0

আমি রেডহ্যাট 6 এবং জিসিসি সংকলকটিতে _ইটোয়া (...) ব্যবহার করেছি। এটা কাজ করে।


0

স্নিপ্রিন্টফের সাথে প্রতিস্থাপনটি সম্পূর্ণ নয়!

এটি কেবল ঘাঁটিগুলি কভার করে: 2, 8, 10, 16, যদিও এটিোয়া 2 এবং 36 এর মধ্যে ঘাঁটিগুলির জন্য কাজ করে।

যেহেতু আমি 32 বেসের জন্য প্রতিস্থাপনটি অনুসন্ধান করছিলাম, আমার ধারণা আমার নিজের কোড করতে হবে!


-4

আপনি স্প্রিন্টফের পরিবর্তে এই প্রোগ্রামটি ব্যবহার করতে পারেন।

void itochar(int x, char *buffer, int radix);

int main()
{
    char buffer[10];
    itochar(725, buffer, 10);
    printf ("\n %s \n", buffer);
    return 0;
}

void itochar(int x, char *buffer, int radix)
{
    int i = 0 , n,s;
    n = s;
    while (n > 0)
    {
        s = n%radix;
        n = n/radix;
        buffer[i++] = '0' + s;
    }
    buffer[i] = '\0';
    strrev(buffer);
}

4
এই কোডটিতে অনেকগুলি বাগ রয়েছে: 1) আসলে হেক্সটিকে সঠিকভাবে রূপান্তর করে না। 2) মোটেই 0 রূপান্তর করে না। 3) নেতিবাচক সংখ্যা নিয়ে কাজ করে না। ৪) বাফারকে ছাড়িয়ে যাওয়ার জন্য কোনও পরীক্ষা করা হচ্ছে না। আমি শীঘ্রই এই কোডটির একটি উন্নত সংস্করণ পোস্ট করব।
ক্রিস দেশজার্ডিনস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.