সি-তে স্ট্রিং-এ কীভাবে রূপান্তর করবেন?


225

আপনি কোন int(পূর্ণসংখ্যা) কে স্ট্রিংয়ে রূপান্তর করবেন ? আমি এমন একটি ফাংশন তৈরির চেষ্টা করছি যা structএকটি ফাইলে সেভ করার জন্য একটি ডেটার একটি স্ট্রিংয়ে রূপান্তর করে ।


3
printfবা এর চাচাত ভাইয়ের
কোনওটি


1
সিরিয়ালাইজেশন সম্পর্কিত আপনি এই FAQ দেখতেও পেতে পারেন এবং সিটিতে সিরিয়ালাইজেশন সম্পর্কিত নিম্নলিখিত প্রশ্নগুলি: (ক) , (খ) , (গ) আপনার আসল অভিপ্রায় অর্জন করতে পারে।
মূইলিপ

2
আমার স্বাভাবিক পোষা প্রাণীকে এখানে অর্থাত্ প্রসারণ করা। আপনি কিছু রূপান্তর করতে চান না; আপনি যদি একটি স্ট্রিং একটি (বেস 10?) এর মান প্রতিনিধিত্ব ধারণকারী প্রাপ্ত করতে চান int। হ্যাঁ আমি জানি. এটি একটি খুব সাধারণ শর্ট কাট, তবে এটি এখনও আমাকে বাগড করে।
ডিএমকেই --- প্রাক্তন-মডারেটর বিড়ালছানা

উত্তর:


92

সম্পাদনা: মন্তব্যে উল্লিখিত হিসাবে, itoa()এটি একটি মান নয়, তাই প্রতিদ্বন্দ্বী উত্তরে প্রস্তাবিত আরও ভাল ব্যবহার স্প্রিন্টফ () করুন!


আপনার পূর্ণসংখ্যার মানটিকে স্ট্রিংয়ে রূপান্তর করতে আপনি itoa()ফাংশনটি ব্যবহার করতে পারেন ।

এখানে একটি উদাহরণ:

int num = 321;
char snum[5];

// convert 123 to string [buf]
itoa(num, snum, 10);

// print our string
printf("%s\n", snum);

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


28
itoaমানসম্মত নয় - উদাহরণস্বরূপ stackoverflow.com/questions/190229/… দেখুন
পল আর

1
@ পলআর এখন আমি জানতাম না! স্পষ্টতার জন্য ধন্যবাদ।
খ্রিস্টান রাউ

1
@ পলআর ধন্যবাদ, আমি এটি জানতাম না!
আলেকজান্ডার গালকিন

@ সিয়েনরেমে এটি itoa()একই বাফার ওভারফ্লো সম্ভাব্যতায় ভুগছে gets()
chux -

আইটোোয়া সি তে পাওয়া যায় না (কমপক্ষে সি 99)। এটি সি ++ এ আরও পাওয়া যায়
মোটি শ্নের

210

আপনি এটি করতে ব্যবহার করতে পারেন sprintf, বা snprintfআপনার যদি এটি থাকতে পারে:

char str[ENOUGH];
sprintf(str, "%d", 42);

যেখানে অক্ষরের সংখ্যা (অতিরিক্ত সমাপ্তি চর) strব্যবহার করে গণনা করা যায়:

(int)((ceil(log10(num))+1)*sizeof(char))

9
ট্যাট ENOUGHযথেষ্ট কিনা তা নিশ্চিত হওয়ার জন্য আমরা এটি করতে পারিmalloc(sizeof(char)*(int)log10(num))
হাউলেথ

2
@Hauleth অথবা +2 এমনকি বিবেচনা করা যে (int)log10(42)হয় 1
খ্রিস্টান রাউ

23
অথবা আপনি এটি সংকলন সময়ে গণনা করতে পারেন:#define ENOUGH ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)
সিএএফ

4
@ হাইলেথ স্টিল +1 এর পরিবর্তে +2, এমনকি সিল সহ: সিল (লগ (100)) = ২.০ নয়, ৩. সুতরাং -10-এর সঠিক-পাওয়ারগুলির জন্য +1, এবং নালটি বন্ধ করার জন্য অন্য একটি +1।
কেবল-ইয়েতি নয়

24
আপনি বিয়োগ চিহ্ন এবং লোকাল বিবেচনা করবেন না: হাজার হাজার বিভাজক এবং গোষ্ঠীকরণ। দয়া করে এটি করুন: int length = snprintf(NULL, 0,"%d",42);দৈর্ঘ্য পেতে ব্যবহার করুন এবং তারপরে length+1স্ট্রিংয়ের জন্য অক্ষর বরাদ্দ করুন ।
ব্যবহারকারী2622016

69

সংক্ষিপ্ত উত্তরটি হ'ল:

snprintf( str, size, "%d", x );

আর লম্বা: প্রথমে আপনাকে পর্যাপ্ত আকার বের করতে হবে। snprintfআপনি NULL, 0প্রথম পরামিতি হিসাবে কল যদি আপনি দৈর্ঘ্য বলুন :

snprintf( NULL, 0, "%d", x );

নাল-টার্মিনেটরের জন্য একটি চরিত্র আরও বরাদ্দ করুন।

#include <stdio.h> 
#include <stdlib.h>

int x = -42;
int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);

যদি প্রতিটি ফর্ম্যাট স্ট্রিংয়ের জন্য কাজ করে, তাই আপনি ব্যবহার করে ফ্লোট বা ডাবল স্ট্রিংয়ে "%g"রূপান্তর করতে পারেন, আপনি ইনটকে হেক্স ব্যবহার করে রূপান্তর করতে পারেন "%x"ইত্যাদি।


3
# অন্তর্ভুক্ত <stdio.h> # অন্তর্ভুক্ত <stdlib.h>
ব্যবহারকারী 1821961

@ ব্যবহারকারী 1821961 ধন্যবাদ, এটি সত্যই উল্লেখ করা উচিত যে এই শিরোলেখ ফাইলগুলি অন্তর্ভুক্ত করা দরকার।
বাইসোর

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

30

জিসিসি-র জন্য ইতোয়ার বিভিন্ন সংস্করণ দেখার পরে, আমি খুঁজে পেয়েছি যে সবচেয়ে নমনীয় সংস্করণটি বাইনারি, দশমিক এবং হেক্সাডেসিমাল রূপান্তরগুলি পরিচালনা করতে সক্ষম, এটি ইতিবাচক এবং নেতিবাচক উভয়ই http://www.strudel.org এ পাওয়া চতুর্থ সংস্করণ .uk / itoa / । যদিও sprintf/ snprintfসুবিধা আছে, তারা দশমিক রূপান্তর ছাড়া অন্য কিছুর জন্য ঋণাত্মক সংখ্যা হ্যান্ডেল করা হবে না। যেহেতু উপরের লিঙ্কটি হয় অফ-লাইন বা আর সক্রিয় নেই, তাই আমি নীচে তাদের চতুর্থ সংস্করণটি অন্তর্ভুক্ত করেছি:

/**
 * C++ version 0.4 char* style "itoa":
 * Written by Lukás Chmela
 * Released under GPLv3.
 */
char* itoa(int value, char* result, int base) {
    // check that the base if valid
    if (base < 2 || base > 36) { *result = '\0'; return result; }

    char* ptr = result, *ptr1 = result, tmp_char;
    int tmp_value;

    do {
        tmp_value = value;
        value /= base;
        *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
    } while ( value );

    // Apply negative sign
    if (tmp_value < 0) *ptr++ = '-';
    *ptr-- = '\0';
    while(ptr1 < ptr) {
        tmp_char = *ptr;
        *ptr--= *ptr1;
        *ptr1++ = tmp_char;
    }
    return result;
}

4
এছাড়াও, এটি স্প্রিন্টফের তুলনায় যথেষ্ট দ্রুত। বড় ফাইল ডাম্প করার সময় গুরুত্বপূর্ণ হতে পারে।
ইউজিন রায়বটসেভ

@ ইউজিন রায়বটসেভ সি এর পারফরম্যান্স রেটিং নির্দিষ্ট করে না sprintf()এবং " এটি স্প্রিন্টফের চেয়ে যথেষ্ট দ্রুত" আপনার সংকলকটিতে সত্য হতে পারে তবে সর্বদা তা ধরে রাখে না। একটি সংকলক sprintf(str, "%d", 42);এটিকে অপ্টিমাইজ করা itoa()মত ফাংশনটিতে সন্ধান করতে এবং এটি অনুকূলিত করতে পারে - অবশ্যই এই ব্যবহারকারীর চেয়ে দ্রুত। কোড।
chux -

3
@ চাক্স হ্যাঁ, একটি সংকলক sprintf(str, "%d", 42);দুটি কনস্ট চরগুলি সংযোজন হিসাবে অনুকূল করতে পারে তবে এটি তত্ত্ব। অনুশীলনে লোকেরা কন্সট ইনটগুলি স্প্রিন্টফ করে না এবং উপরের আইটোোয়াটি প্রায় যতটা অনুকূল হবে ততই অনুকূলিত। কমপক্ষে আপনি 100% নিশ্চিত হতে পারেন যে আপনি জেনেরিক স্প্রিন্টফের মাত্রা ডাউনগ্রেডের অর্ডার পাবেন না। সংকলক সংস্করণ এবং সেটিংস সহ আপনার মনে থাকা কাউন্টারিক্স নমুনাটি দেখে ভাল লাগবে।
ইউজিন রায়বটসেভ

1
@chux যদি এটি একটি কলটিতে শেষ হয় তবে আমরা উপরের রুটিনের সাথে কল করা রুটিনের তুলনা না করা (এটি সমস্ত ধরণের রাস্তায় আর কল করা যাবে না; সমাবেশে, যদি আপনি চান) তবে এটি খুব বেশি ব্যাখ্যা করে না। আপনি যদি সংকলক সংস্করণ এবং সেটিংস সহ উত্তর হিসাবে এটি করেন, আমি এটি দরকারী হিসাবে upvote করব।
ইউজিন রায়বতসেভ

2
আউটপুট দৈর্ঘ্য ফিরে পাওয়ার কোনও উপায় সরবরাহ করা ভাল। আমি এটি এখানে করেছি: stackoverflow.com/a/52111436/895245 + ইউনিট পরীক্ষা tests
সিরো সান্তিলি 郝海东 冠状 病 六四 事件

9

এটি পুরানো তবে এখানে অন্য উপায়।

#include <stdio.h>

#define atoa(x) #x

int main(int argc, char *argv[])
{
    char *string = atoa(1234567890);
    printf("%s\n", string);
    return 0;
}

32
কেবল স্থায়ীদের জন্য কাজ করে, ভেরিয়েবলের জন্য নয়।
নেকডেবল

7

আপনি যদি জিসিসি ব্যবহার করে থাকেন তবে আপনি জিএনইউ এক্সটেনশন অ্যাসপ্রিন্টফ ফাংশনটি ব্যবহার করতে পারেন।

char* str;
asprintf (&str, "%i", 12313);
free(str);

7

যে কোনও কিছুকে স্ট্রিংয়ে রূপান্তর করা উচিত 1) ফলস্বর স্ট্রিং বরাদ্দ করা উচিত বা 2) কোনও char *গন্তব্য এবং আকারে পাস । নীচে নমুনা কোড:

উভয় intসহ সকলের জন্য কাজ করে INT_MIN। তারা একটি সামঞ্জস্যপূর্ণ আউটপুট সরবরাহ snprintf()করে যা বর্তমান লোকেলের উপর নির্ভর করে।

পদ্ধতি 1: NULLমেমরির বাইরে চলে আসে।

#define INT_DECIMAL_STRING_SIZE(int_type) ((CHAR_BIT*sizeof(int_type)-1)*10/33+3)

char *int_to_string_alloc(int x) {
  int i = x;
  char buf[INT_DECIMAL_STRING_SIZE(int)];
  char *p = &buf[sizeof buf - 1];
  *p = '\0';
  if (i >= 0) {
    i = -i;
  }
  do {
    p--;
    *p = (char) ('0' - i % 10);
    i /= 10;
  } while (i);
  if (x < 0) {
    p--;
    *p = '-';
  }
  size_t len = (size_t) (&buf[sizeof buf] - p);
  char *s = malloc(len);
  if (s) {
    memcpy(s, p, len);
  }
  return s;
}

পদ্ধতি 2: NULLবাফারটি খুব কম থাকলে এটি ফিরে আসে ।

static char *int_to_string_helper(char *dest, size_t n, int x) {
  if (n == 0) {
    return NULL;
  }
  if (x <= -10) {
    dest = int_to_string_helper(dest, n - 1, x / 10);
    if (dest == NULL) return NULL;
  }
  *dest = (char) ('0' - x % 10);
  return dest + 1;
}

char *int_to_string(char *dest, size_t n, int x) {
  char *p = dest;
  if (n == 0) {
    return NULL;
  }
  n--;
  if (x < 0) {
    if (n == 0) return NULL;
    n--;
    *p++ = '-';
  } else {
    x = -x;
  }
  p = int_to_string_helper(p, n, x);
  if (p == NULL) return NULL;
  *p = 0;
  return dest;
}

@ অল্টার মন দ্বারা অনুরোধ হিসাবে [সম্পাদনা করুন]

(CHAR_BIT*sizeof(int_type)-1)*10/33+3charsignedচ্ছিক নেতিবাচক চিহ্ন, অঙ্কগুলি এবং একটি নাল অক্ষর সমন্বিত স্ট্রিং হিসাবে কিছু স্বাক্ষরিত পূর্ণসংখ্যার টাইপটিকে এনকোড করার জন্য কমপক্ষে প্রয়োজনীয় সংখ্যার প্রয়োজন হয় ..

একটি স্বাক্ষরিত পূর্ণসংখ্যায় স্বাক্ষরবিহীন বিটের সংখ্যা আর বেশি নয় CHAR_BIT*sizeof(int_type)-1। একটি- nবিট বাইনারি সংখ্যার একটি বেস -10 উপস্থাপনা n*log10(2) + 1অঙ্ক পর্যন্ত লাগে । 10/33চেয়ে সামান্য বেশি হয় log10(2)। চিহ্নটির জন্য char+1 এবং শূন্য চরিত্রের জন্য +1। অন্যান্য ভগ্নাংশগুলি 28/93 এর মতো ব্যবহার করা যেতে পারে।


পদ্ধতি 3: এক কিনারায় বাস এবং বাফার ওভারফ্লো একটি উদ্বেগের বিষয় নয় করতে চায়, একটি সহজ C99 বা পরে সমাধান যা পরিচালনা অনুসরণ করে সব int

#include <limits.h>
#include <stdio.h>

static char *itoa_simple_helper(char *dest, int i) {
  if (i <= -10) {
    dest = itoa_simple_helper(dest, i/10);
  }
  *dest++ = '0' - i%10;
  return dest;
}

char *itoa_simple(char *dest, int i) {
  char *s = dest;
  if (i < 0) {
    *s++ = '-';
  } else {
    i = -i;
  }
  *itoa_simple_helper(s, i) = '\0';
  return dest;
}

int main() {
  char s[100];
  puts(itoa_simple(s, 0));
  puts(itoa_simple(s, 1));
  puts(itoa_simple(s, -1));
  puts(itoa_simple(s, 12345));
  puts(itoa_simple(s, INT_MAX-1));
  puts(itoa_simple(s, INT_MAX));
  puts(itoa_simple(s, INT_MIN+1));
  puts(itoa_simple(s, INT_MIN));
}

নমুনা আউটপুট

0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648

আরে চুকস, আপনি কি জানেন যে গ্লাবসি অভ্যন্তরীণ বাস্তবায়নটি প্রকাশ করার কোনও উপায় আছে কিনা? সোর্সওয়্যার.আর.জি.গিট
/?p=glibc.git ;a=blob ;f=stdio-

1
@CiroSantilli 新疆 改造 中心 六四 事件 法轮功 আমি গ্লিবসি অভ্যন্তরীণ প্রয়োগের সাথে পরিচিত নই।
chux - মনিকা পুনরায় স্থাপন 15

3
/*Function return size of string and convert signed  *
 *integer to ascii value and store them in array of  *
 *character with NULL at the end of the array        */

int itoa(int value,char *ptr)
     {
        int count=0,temp;
        if(ptr==NULL)
            return 0;   
        if(value==0)
        {   
            *ptr='0';
            return 1;
        }

        if(value<0)
        {
            value*=(-1);    
            *ptr++='-';
            count++;
        }
        for(temp=value;temp>0;temp/=10,ptr++);
        *ptr='\0';
        for(temp=value;temp>0;temp/=10)
        {
            *--ptr=temp%10+'0';
            count++;
        }
        return count;
     }

2

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


-2

ফাংশন ব্যবহার করুন itoa()একটি রূপান্তর করতে পূর্ণসংখ্যা একটি থেকে স্ট্রিং

উদাহরণ স্বরূপ:

char msg[30];
int num = 10;
itoa(num,msg,10);

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.