C में 1123456789 से 1,123,456,789 तक संख्या कैसे प्रारूपित करें?


83

कैसे कर सकते हैं मैं सी भाषा प्रारूप में से एक नंबर 1123456789के लिए 1,123,456,789? मैं का उपयोग करने की कोशिश की, printf("%'10d\n", 1123456789);लेकिन यह काम नहीं करता है।

क्या आप कुछ भी सलाह दे सकते हैं? समाधान जितना आसान होगा उतना ही अच्छा होगा।


1
सिर्फ एक FYI: printf()स्वरूपित IO फ़ंक्शंस (एकल-भाव वर्ण: ') के परिवार के लिए' हजारों विभाजक 'ध्वज एक गैर-मानक ध्वज है जो केवल कुछ लाइब्रेरी कार्यान्वयन में समर्थित है। यह बहुत बुरा है कि यह मानक नहीं है।
माइकल बूर

1
यह स्थानीय-निर्भर है। लिनक्स मैन पेज के अनुसार , यह दिखता है LC_NUMERIC। हालाँकि, मुझे नहीं पता कि यह किस लोकेल का समर्थन करता है।
जॉय एडम्स

1
@ जॉय, LC_NUMERICलोकल को करंट में सेट करना मेरे मैक पर काम ""करता है 'और एक लाइनक्स मशीन पर जिसे मैंने अभी चेक किया है।
कार्ल नॉरम जूल

ध्यान दें कि printf()फ़ंक्शन के परिवार के POSIX 2008 (2013) संस्करण 'दशमलव संख्या स्वरूपण विनिर्देशों के साथ (एकल उद्धरण या एपोस्ट्रोफ़) वर्ण के उपयोग को मानकीकृत करते हैं ताकि यह निर्दिष्ट किया जा सके कि संख्या को हजारों विभाजकों के साथ स्वरूपित किया जाना चाहिए।
जोनाथन लेफ़लर

2
यह भी ध्यान दें कि डिफ़ॉल्ट "C"लोकेल में, गैर-मौद्रिक हजारों विभाजक अपरिभाषित हैं, इसलिए लोकेल "%'d"में कॉमा उत्पन्न नहीं करेगा "C"। आपको एक उपयुक्त गैर-मौद्रिक हजार विभाजक के साथ एक स्थान निर्धारित करने की आवश्यकता है। अक्सर, setlocale(LC_ALL, "");काम करेंगे - स्थानीय नाम (खाली स्ट्रिंग के अलावा) के लिए अन्य मूल्यों को परिभाषित किया गया है।
जोनाथन लेफ़लर

जवाबों:


83

यदि आपका प्रिंटफ़ 'फ्लैग का समर्थन करता है (जैसा कि POSIX 2008 के लिए आवश्यक है printf()), तो आप इसे उचित रूप से अपना लोकेल सेट करके ही कर सकते हैं। उदाहरण:

और निर्माण और चलाने:

मैक ओएस एक्स और लिनक्स (उबंटू 10.10) पर परीक्षण किया गया।


1
मैं sprintf()एक एम्बेडेड सिस्टम में इस पर परीक्षण किया है और यह काम नहीं करता है (जाहिर है, क्योंकि जैसा कि आप कहते हैं, यह 'ध्वज का समर्थन नहीं करेगा।
gbmhunter

मुझे यकीन है कि आप एक सी लाइब्रेरी पा सकते हैं जो बहुत अधिक परेशानी के बिना इसका समर्थन करेगी।
कार्ल नॉरम

मेरे पास एक त्वरित नज़र थी, कुछ भी उपयुक्त नहीं मिला, और ऊपर दिए गए कुछ विचारों का उपयोग करके अपने खुद को लागू किया। एक वास्तविक पुस्तकालय खोजना बहुत अच्छा होगा, ताकि आप इसे दशमलव स्थानों के साथ फ़्लोट्स और तारों पर उपयोग कर सकें।
gbmhunter

1
FWIW AtmelStudio के एम्बेडेड सिस्टम printf () का दुखद अंत दिखाई देता है नहीं समर्थन करने के लिए 'आपरिवर्तक। हेडर से: Copyright ... 2007 Joerg Wunsch ... 1993 Regents of the University of Californiaयानी एक बीएसडी व्युत्पन्न।
बॉब स्टीन

2
हालांकि यह आसान है - आप इस कार्यक्षमता (सेटलोकेल) के लिए राज्य को बदलना नहीं चाहते हैं।
ideasman42

46

आप इसे निम्नानुसार कर सकते हैं (सावधान रहें INT_MINयदि आप दो के पूरक का उपयोग कर रहे हैं, तो आपको इसे प्रबंधित करने के लिए अतिरिक्त कोड की आवश्यकता होगी):

एक सारांश:

  • उपयोगकर्ता printfcommaएक पूर्णांक के साथ कॉल करता है , नकारात्मक संख्याओं के विशेष मामले को केवल "-" और संख्या को सकारात्मक बनाते हुए नियंत्रित किया जाता है (यह वह बिट है जो काम नहीं करेगा INT_MIN)।
  • जब आप दर्ज करते हैं printfcomma2, तो 1,000 से कम की संख्या सिर्फ प्रिंट और वापस आ जाएगी।
  • अन्यथा पुनरावृत्ति को अगले स्तर तक कहा जाएगा (इसलिए 1,234,567 को 1,234 के साथ बुलाया जाएगा, फिर 1) जब तक कि 1,000 से कम की संख्या न मिल जाए।
  • फिर उस नंबर को प्रिंट किया जाएगा और हम चलते हुए रिकर्सन ट्री को वापस करेंगे, कॉमा और अगले नंबर को प्रिंट करते हुए।

अधिक रसीला संस्करण भी है, हालांकि यह हर स्तर पर नकारात्मक संख्याओं की जांच करने में अनावश्यक प्रसंस्करण करता है (ऐसा नहीं है कि यह सीमित संख्या में पुनरावृत्ति स्तरों को बताएगा)। यह एक परीक्षण का पूरा कार्यक्रम है:

और आउटपुट है:


उन लोगों के लिए एक पुनरावृत्ति समाधान, जो पुनरावृत्ति पर भरोसा नहीं करते हैं (हालांकि पुनरावृत्ति के साथ एकमात्र समस्या स्टैक स्पेस होती है, जो यहां एक मुद्दा नहीं होगा क्योंकि यह 64-बिट पूर्णांक के लिए भी कुछ ही स्तर गहरा होगा):

इन दोनों के 2,147,483,647लिए उत्पन्न करते हैं INT_MAX


उपरोक्त सभी कोड अल्प-पृथक तीन-अंकीय समूहों के लिए है, लेकिन आप अन्य वर्णों का भी उपयोग कर सकते हैं, जैसे कि एक स्थान:


मुझे लगता है कि इसे पुनरावृत्त रूप से हल किया जाना चाहिए, क्योंकि समस्या पुनरावृत्ति की तुलना में अधिक स्वाभाविक रूप से पुनरावृत्ति ("प्रत्येक तीसरे अंक को अलग करती है") ("बाकी से तीसरे अंक को अलग करें, फिर बाकी पर यह दोहराएं")।
जोरेन

MIN_INT के लिए सुझाए गए सुधार: अहस्ताक्षरित int लेने के लिए printfcomma2 बदलें। बस। बहुत ज्यादा नहीं "अतिरिक्त कोड" :-)
स्टीव जेसप

@ जोरेन: मैंने एक पुनरावृत्त समाधान जोड़ा है, और कुछ हद तक यह दर्शाता है कि पुनरावर्ती समाधान में योग्यता क्यों है। हालांकि कई मामलों में पुनरावृत्ति से बचना एक कोडिंग मानकों का मुद्दा है।
क्लिफोर्ड

@ साइट: केवल तर्क प्रकार बदलने से यह ठीक नहीं होता क्योंकि UB को जैसे ही आप नेगेट में डाला जाता nहै printfcomma। आपको इसे नकारने से पहले किसी रूपांतरण को बाध्य करने की आवश्यकता है।
R .. GitHub STOP हेल्पिंग ICE

1
@ निहाल, यह इस अर्थ में फिर से शुरू नहीं होता है कि सभी वर्तमान प्रगति खो गई है। यह अपने आप पुनरावर्ती कॉल और फिर अगले बयान में वापस आ जायेगा printf
पाक्सिडाब्लो

11

यहाँ एक बहुत ही सरल कार्यान्वयन है। इस फ़ंक्शन में कोई त्रुटि जाँच नहीं है, कॉलर द्वारा बफर आकारों को सत्यापित किया जाना चाहिए। यह नकारात्मक संख्याओं के लिए भी काम नहीं करता है। ऐसे सुधार पाठक के लिए एक अभ्यास के रूप में छोड़ दिए जाते हैं।


मुझे यह पसंद है, यह प्रिंटफ के बजाय स्प्रिंट का उपयोग करता है, जो एम्बेडेड सिस्टम के लिए उपयोगी है।
gbmhunter

1
काफी अच्छा है, लेकिन नकारात्मक संख्याओं के लिए काम करने के लिए कुछ मामूली मोड़ की जरूरत होती है।
विचारमान 42

(नकारात्मक संख्या समर्थन stackoverflow.com/a/24795133/432509 के लिए संशोधित संस्करण )
ideasman42

5

ओह नहीं! मैं हर समय ऐसा करता हूं, linux पर gcc / g ++ और glibc का उपयोग करके, और 'ऑपरेटर गैर-मानक हो सकता है, लेकिन मुझे इसकी सरलता पसंद है।

का आउटपुट देता है:

बड़ी संख्या: 12,345,678

बस वहां पर 'सेटलोकेले' कॉल को याद रखना होगा, अन्यथा यह कुछ भी प्रारूपित नहीं करेगा।


2
अफसोस की बात है, यह विंडोज / जीसीसी 4.9.2 में काम नहीं करता है।
rdtsc

अच्छी तरह से Drat! मुझे लगा होगा कि किसी भी प्लेटफ़ॉर्म पर gcc OS की परवाह किए बिना समान परिणाम देगा। अच्छा लगता है कि मुझे लगता है, आश्चर्य है कि हालांकि क्यों।
हम्म्म्म

ध्यान दें कि यदि उपयोग में लाई जाने वाली सी लाइब्रेरी 'ध्वज का समर्थन नहीं करती है , तो आपको वांछित आउटपुट नहीं मिलता है - और यह कंपाइलर से स्वतंत्र है। संकलक यह सुनिश्चित करता है कि लाइब्रेरी फ़ंक्शन printf()को प्रारूप स्ट्रिंग के साथ बुलाया जाए; यह व्याख्या करने के लिए पुस्तकालय समारोह पर निर्भर है। विंडोज पर, यह पूरी तरह से संभव है कि सीआरटी पुस्तकालय आपको आवश्यक समर्थन प्रदान नहीं करता है - और यह मायने नहीं रखता है कि आप किस कंपाइलर का उपयोग करते हैं।
जोनाथन लेफलर

3

शायद एक स्थानीय-जागरूक संस्करण दिलचस्प होगा।

यह एक बग है (लेकिन एक मैं काफी मामूली विचार करेंगे)। दो के पूरक हार्डवेयर पर, यह सबसे-ऋणात्मक संख्या को सही ढंग से परिवर्तित नहीं करेगा, क्योंकि यह नकारात्मक संख्या को इसके समकक्ष सकारात्मक संख्या में बदलने का प्रयास करता है N = -N;। दो के पूरक में, अधिकतम नकारात्मक संख्या में एक समान धनात्मक संख्या नहीं होती है, जब तक कि आप इसे बड़े प्रकार तक बढ़ावा दें। इसके चारों ओर जाने का एक तरीका संख्या को संबंधित अहस्ताक्षरित प्रकार को बढ़ावा देना है (लेकिन यह कुछ हद तक गैर-तुच्छ है)।


मैंने एक सवाल पूछा था कि प्रारूप- 'फ़्लैग के क्रॉस प्लेटफ़ॉर्म कार्यान्वयन के लिए और अधिक निर्देश यहां दिए गए हैं: stackoverflow.com/q/44523855/2642059 मुझे लगता है कि यह जवाब पूरी तरह से पता है कि, अब और परीक्षण कर रहा है। अगर ऐसा है तो मुझे लगता है कि मुझे उस सवाल को एक ठग के रूप में चिह्नित करना चाहिए?
जोनाथन मी

ठीक है, पहली चीज़ जो मैंने पहचानी है, वह स्थानीय समायोजन के रूप में समायोजित नहीं होती है। क्यों बनाए रखने, tsep, place_str, और neg_strसब पर? क्यों नहीं सीधे सीधे fmt_infoसदस्यों का उपयोग करें ?
जोनाथन मी

ठीक है, नंबर चीज़ नंबर 2, यह कोड नकारात्मक संख्याओं को संभाल नहीं सकता है ... और मुझे नहीं पता कि यह कैसे हो सकता है, while (*ptr-- = *neg_str++)इससे मुझे कोई मतलब नहीं है। आप नकारात्मक स्ट्रिंग वर्णों को उल्टे क्रम में सम्मिलित कर रहे हैं।
जोनाथन मी

तो ... मैंने स्मृति रिसाव को समाप्त कर दिया है, और बग को नकारात्मक संख्याओं के साथ ठीक कर दिया है: ideone.com/gTv8Z4 दुर्भाग्य से अभी भी एक मुद्दा है जिसमें कई चरित्र विभाजक या एकाधिक चरित्र नकारात्मक प्रतीकों के पीछे स्ट्रिंग को लिखा जा रहा है। मैं इसे अगले हल करने की कोशिश करने जा रहा हूं ...
योनातन मी

@JonathanMee: मैंने कोड अपडेट किया है (और कम से कम कुछ और परीक्षण मामलों को जोड़ा है, जिसमें नकारात्मक संख्याएं शामिल हैं)।
जेरी कॉफिन

2

पुनरावृत्ति या स्ट्रिंग हैंडलिंग के बिना, एक गणितीय दृष्टिकोण:

पैक्स के पुनरावर्ती समाधान के सिद्धांत में समान है, लेकिन अग्रिम में परिमाण के क्रम की गणना करके, पुनरावृत्ति से बचा जाता है (कुछ काफी व्यय पर)।

यह भी ध्यान दें कि हजारों को अलग करने के लिए उपयोग किया जाने वाला वास्तविक चरित्र स्थानीय विशिष्ट है।

संपादित करें : सुधार के लिए नीचे @ Chux की टिप्पणियां देखें।


1
बदलने abs(n)के लिए fabs(n)रोकता है 2 के तारीफ त्रुटि प्रदर्शन print_number(INT_MIN)
chux -

@chux: अच्छी बात है, लेकिन% अभिव्यक्ति में, LHS वापस एक इंट में डाली जाएगी और यह अभी भी टूट जाएगा। यह संभव है कि केवल स्वीकार्य इनपुट की थोड़ी सी छोटी सीमा को स्वीकार करना या INT_MIN के लिए सीधे एक परीक्षण और आउटपुट "-2,147,483,647" जोड़ना, (या जो भी INT_MIN प्रश्न में मंच पर है - उसमें कीड़े की एक और इच्छा हो सकती है।
Clifford

मैंने सुझाव देने से पहले इसका सफल परीक्षण किया। हममम। मुझे लगता है कि मेरा विचार केवल log10(abs(n))और कहीं नहीं के लिए था। दिलचस्प बात यह है अपने समाधान करने के लिए एक परिवर्तन के साथ काम करता log10(fabs(n))है और print_number(INT_MIN)इस वजह से printf(..., abs(n / order_of_magnitude))जो साधन n = abs(INT_MIN) % order_of_magnitudeनकारात्मक किया जा रहा है ठीक है। अगर हम INT_MIN पर हार मानते हैं, तो printf(..., abs(n / order_of_magnitude))बन सकते हैं printf(..., n / order_of_magnitude)। लेकिन मुझे लगता है कि "एब्स (INT_MIN)" नामक कीड़ा के साथ काम करना आमतौर पर एक बुरी बात है।
chux -

नया विचार: 3 परिवर्तन सुझाए log10(fabs(n)), n = abs(n% order_of_magnitude)और printf(",%03d", n/order_of_magnitude)। BTW: मैं इस प्रयास को तब तक नहीं बिताऊंगा जब तक मुझे नहीं लगता कि आप समाधान अच्छा था। INT_MIN के लिए भी कोई UB नहीं।
chux -

2

@Greg Hewgill के आधार पर, लेकिन नकारात्मक संख्याओं को ध्यान में रखता है और स्ट्रिंग आकार को लौटाता है।


1

मेरा उत्तर वास्तव में प्रश्न में चित्रण की तरह परिणाम को प्रारूपित नहीं करता है, लेकिन एक साधारण एक-लाइनर या मैक्रो के साथ कुछ मामलों में वास्तविक आवश्यकता को पूरा कर सकता है । आवश्यक के रूप में अधिक हजार-समूह उत्पन्न करने के लिए इसका विस्तार किया जा सकता है।

परिणाम उदाहरण के लिए दिखेगा:

Value: 0'000'012'345

कोड:


क्या विश्व के किसी भाग (नों) में 'एक मानक अंकन ,(गणितीय रूप से, कम से कम) के बराबर है ?
१३

1
@ysap यह दुनिया के कुछ हिस्सों में एक हजार विभाजक है।
रोलैंड पिहलाकास

0

सी में ऐसा करने का कोई वास्तविक सरल तरीका नहीं है। मैं इसे करने के लिए एक इंट-टू-स्ट्रिंग फ़ंक्शन को संशोधित करूंगा:


0

एक और पुनरावृत्त समारोह


मैं सरणी के आयाम को निर्धारित करने के लिए उपयोग की जाने वाली अभिव्यक्ति से सहमत हूं! " क्या इसके लिए गणितीय औचित्य है?
क्लिफोर्ड

प्रत्येक दशमलव अंक के लिए ld (10) बिट्स। 3. नीचे राउंड करें। हम 3 को फिर से विभाजित कर सकते हैं (इस तथ्य के लिए कि हम एक बार में 3 अंक तक स्टोर करते हैं)। लेकिन मैं इसे ऊपरी सीमा पर रखना चाहता था।
जोहान्स शहाब -

0

इस प्रकार के दशमलव अंकों को बनाने का सबसे पतला, आकार और गति कुशल कार्यान्वयन है:

निम्नानुसार उपयोग करें:

आउटपुट:

कुछ फायदे:

  • रिवर्स ऑर्डर किए गए फॉर्मेटिंग के कारण स्ट्रिंग बफर के अंत में कार्य करना। अंत में, उत्पन्न स्ट्रिंग (स्ट्रिव) को वापस करने की कोई आवश्यकता नहीं है।

  • यह फ़ंक्शन एक स्ट्रिंग का उत्पादन करता है जिसे बाद में किसी भी अहंकार में इस्तेमाल किया जा सकता है। यह निर्भर नहीं करता है और न ही कई प्रिंटफ / स्प्रिंटफ कॉल की आवश्यकता है, जो भयानक धीमी और हमेशा संदर्भ विशिष्ट है।

  • डिवाइड ऑपरेटरों की न्यूनतम संख्या (/,%)।

क्या है unlikely?
दान बेचार

1
@Dan: unlikelyसंभवतः ऑप्टिमाइज़र को संकेत है कि स्थिति सही होने की संभावना नहीं है। अधिक जानकारी के लिए लिनक्स कर्नेल में देखें likely()/ unlikely()मैक्रो
जोनाथन लेफ़लर

@JonathanLeffler ओह, हुह। लिंक के लिए धन्यवाद।
डैन बेहार्ड

0

नेगेटिव नंबरों के साथ फ़ॉर्मेट_कम करें,

क्योंकि वीएस <2015 स्निपरफ को लागू नहीं करता है, आपको ऐसा करने की आवश्यकता है

और तब

उदाहरण उपयोग:


0

@Paxdiablo समाधान का एक संशोधित संस्करण, लेकिन उपयोग WCHARऔर wsprinf:


0

मैं C प्रोग्रामिंग में नया हूँ। यहाँ मेरा सरल कोड है।


0

मेरे समाधान का उपयोग करता है a। इसके बजाय इसे बदलने के लिए पाठक पर छोड़ दिया जाता है।


0

यह पुराना है और इसके बहुत सारे उत्तर हैं लेकिन सवाल यह नहीं था कि "मैं कॉमा को जोड़ने के लिए एक दिनचर्या कैसे लिख सकता हूं" लेकिन "यह सी में कैसे किया जा सकता है"? टिप्पणियों ने इस दिशा की ओर इशारा किया लेकिन जीसीसी के साथ मेरे लिनक्स सिस्टम पर, यह मेरे लिए काम करता है:

जब यह चलाया जाता है, तो मुझे मिलता है:

यदि मैं LC_ALLप्रोग्राम को चलाने से पहले वेरिएबल को अनसेट करता हूं , unsetenvतो यह आवश्यक नहीं है।


0

खुद कुछ ऐसा ही करने की जरूरत है, बल्कि सीधे छापने के बजाय, एक बफर में जाने की जरूरत है। यहाँ मैं क्या लेकर आया हूँ। पीछे की ओर काम करता है।

ध्यान रखें कि यह केवल अहस्ताक्षरित पूर्णांक के लिए डिज़ाइन किया गया है और आपको यह सुनिश्चित करना होगा कि बफर काफी बड़ा है।


0

एक अन्य समाधान, परिणाम को एक intसरणी में सहेजकर , अधिकतम 7 का आकार क्योंकि long long intप्रकार 9,223,372,036,854,775,807 से -9,223,372,036,854,785,807 की सीमा में संख्या को संभाल सकता है । (ध्यान दें कि यह एक अहस्ताक्षरित मूल्य नहीं है)।

गैर-पुनरावर्ती मुद्रण कार्य

मुख्य समारोह कॉल

परीक्षण उत्पादन

मुख्य () फ़ंक्शन में:

यदि मुद्रण की आवश्यकता है, तो int numberSeparated[8];फ़ंक्शन के अंदर जाएं getNumWcommasऔर इसे इस तरह से कॉल करें getNumWcommas(number)


-1

बहुत आसानी से किया जा सकता है ...

उदाहरण कॉल:


-1

1
कोड पोस्ट करते समय कम से कम इंडेंटेशन का उपयोग करें। इसके अलावा शायद कुछ स्पष्टीकरण जोड़ें कि यह क्या करता है कि मौजूदा उत्तर अभी तक नहीं करते हैं।
इवित

इसमें सरलता का गुण है और इसे एक नज़र में आसानी से समझा जा सकता है।
स्टीवन न्यूमैन

1
फर्जी समाधान, ,नीचे दिए गए नंबरों के लिए एक अतिरिक्त प्रिंट 100करता है, उपयोग करता है printf()जहां putchar()उड़ जाएगा, भ्रामक नाम, अराजक इंडेंटेशन और बहुत अधिक कोड का उपयोग करता है।
चकरली

-1

1
इस कोड में कई तरह की समस्याएं हैं। अप्रयुक्त चर idxजा सकता है। कोड 0. के लिए कुछ भी उत्पादन नहीं करता है। यह नकारात्मक संख्याओं को संभालता नहीं है। bufferएक staticचर बनाने का कोई स्पष्ट कारण नहीं है (यह कोड की पुनर्व्यवस्थितता को सीमित करता है)। इसका कोई स्पष्टीकरण नहीं है कि यह क्या करता है, या यह उल्लेख करता है कि कोड पूरा होने के बाद, स्ट्रिंग द्वारा इंगित स्ट्रिंग pमें स्वरूपित स्ट्रिंग शामिल है। सबसे कम गंभीर समस्या यह है कि यह हजारों विभाजक के रूप में अल्पविराम के बजाय रिक्त का उपयोग करता है। तथ्य यह है कि यह शून्य को संभाल नहीं करता है, हालांकि हत्यारा समस्या है।
जोनाथन लेफ़लर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.