2015-03-16 7 views
7

लक्ष्य: जेएसओएन को डेटा क्रमबद्ध करें।sprintf उत्पन्न होने वाले आउटपुट की लंबाई की गणना कैसे करें?

अंक: मैं पहले से नहीं जानता कि पूर्णांक कितने अक्षर लंबे हैं।

मैं का उपयोग कर sprintf()

size_t length = sprintf(no_buff, "{data:%d}",12312); 
char *buff = malloc(length); 
snprintf(buff, length, "{data:%d}",12312); 
//buff is passed on ... 
बेशक

मैं char a[256] बजाय no_buff की तरह एक ढेर चर का उपयोग कर सकते हैं द्वारा सोचा है यह करने के लिए एक अच्छा तरीका है।

प्रश्न: लेकिन क्या सी में यूसी /dev/null जैसे डिस्पोजेबल लिखने के लिए उपयोगिता है? Smth इस तरह:

#define FORGET_ABOUT_THIS ... 
size_t length = sprintf(FORGET_ABOUT_THIS, "{data:%d}",12312); 

पी.एस. मुझे पता है कि मैं लॉग के माध्यम से पूर्णांक की लंबाई भी प्राप्त कर सकता हूं लेकिन यह तरीके अच्छे लगते हैं।

+0

लंबाई को काम करने के लिए http://stackoverflow.com/questions/1068849/how-do-i-determine-the-number-of-digits-of-an-integer-in-c –

+0

संभावित डुप्लिकेट [ स्प्रिंटफ बफर आकार निर्धारित करना - मानक क्या है?] (Http://stackoverflow.com/questions/3919995/determining-sprintf-buffer-size-whats-the- standard) –

उत्तर

8

चूंकि सी सरल भाषा है, वहां "डिस्पोजेबल बफर" जैसी कोई चीज़ नहीं है - सभी मेमोरी प्रबंधन प्रोग्रामर कंधों पर हैं (इनके लिए जीएनयू सी कंपाइलर एक्सटेंशन हैं लेकिन वे मानक नहीं हैं)।

पहले से नहीं जानता कि पूर्णांक कितने लंबे समय तक हैं।

आपकी समस्या के लिए बहुत आसान समाधान है। snprintf जानता है!

C99-संगत प्लेटफार्मों पर पहले तर्क के रूप में शून्य के साथ snprintf फोन:

ssize_t bufsz = snprintf(NULL, 0, "{data:%d}",12312); 
char* buf = malloc(bufsz + 1); 
snprintf(buf, bufsz + 1, "{data:%d}",12312); 

... 

free(buf); 

पुराने दृश्य स्टूडियो संस्करण (जो गैर C99 संगत सीआरटी है) में, snprintf(NULL, ...) कॉल के बजाय _scprintf का उपयोग करें।

+1

विजुअल स्टूडियो नहीं (कम से कम हाल के संस्करणों में) '_snprintf' नामक फ़ंक्शन का समर्थन करता है जो मानक 'snprintf' के समान है? –

+0

@ किथ थॉम्पसन: एमएसडीएन की जांच की, ऐसा लगता है कि वीएस2013 से शुरू करने से उन्होंने इसे ठीक किया। नोट के लिए धन्यवाद, मैंने अपना उत्तर – myaut

+1

अपडेट किया है नोट: 'snprintf() 'भी वापस आ सकता है और कोने स्थितियों में परेशानी है क्योंकि' size_t' और 'int' का अधिकतम मान शायद ही कभी समान होता है। 2 'snprintf() 'के बीच' लोकेल 'परिवर्तन होना चाहिए और दूसरा' आउटपुट लंबा होना चाहिए। – chux

10

आप कितनी जगह की आवश्यकता है इसका परीक्षण करने के लिए आप int len = snprintf(NULL, 0, "{data:%d}", 12312) पर कॉल कर सकते हैं।

snprintf, ज्यादा से ज्यादा size वर्ण प्रिंट होगा जहां size दूसरा तर्क है, और वापसी कितने वर्ण पूरी बात मुद्रित करने के लिए, समाप्त '\0' गिनती नहीं आवश्यक हो गया होता। चूंकि आप 0 में गुजरते हैं, यह वास्तव में कुछ भी नहीं लिखता है (और इस प्रकार किसी भी शून्य सूचक अपवाद से बच जाएगा जो NULL को अपमानित करने की कोशिश करके होगा), लेकिन यह अभी भी पूरे आउटपुट को फिट करने के लिए आवश्यक लंबाई को वापस कर देगा, जो आप अपने बफर आवंटित करने के लिए उपयोग कर सकते हैं।

char *buf = malloc(len + 1); 
snprintf(buf, len + 1, "{data:%d}", 12312); 
+0

ग्रेट, धन्यवाद। वास्तव में मुझे क्या चाहिए। मजेदार यह त्वरित संदर्भ में नहीं था। मुझे लगता है कि अनुभव के लिए क्या मात्रा है। सादर – alknows

+1

आपको यह भी उल्लेख करना चाहिए कि यदि एक नल बफर का उपयोग किया जाता है तो यह स्ट्रिंग समाप्ति की गणना नहीं करेगा। http://en.cppreference.com/w/c/io/fprintf – alknows

+0

@Aldi उस स्पष्टीकरण को शामिल करने के लिए अद्यतन करने के लिए धन्यवाद। –

5

सिर्फ लंबाई प्राप्त करने के लिए आप लिख सकते हैं::

int length = snprintf(NULL, 0, "{data:%d}", 12312); 

नोट

उस बिंदु आप आबंटित कर अपने बफर करने के लिए मुद्रित कर सकते हैं, याद है पर के लिए अनुगामी '\0' एक और शामिल करने के लिए कि वापसी का प्रकार int है। किसी प्रकार की त्रुटि के मामले में यह -1 लौटा सकता है। सुनिश्चित करें कि आपके इनपुट डेटा में लंबे तार शामिल नहीं हैं जो कुल लंबाई INT_MAX से अधिक हो सकता है!

+0

आप आसानी से अधिकतम आकार (10 मानते हुए 32 बिट्स) + 8 की गणना कर सकते हैं - तो 18 –

+0

@EdHeal मेरा समाधान प्रकारों के आकारों के बारे में कोई धारणा नहीं बनाता है। मुझे यकीन है कि वहां बहुत सारे कोड हैं जो 64-बिट लक्ष्य के लिए पुन: संकलित होने के कारण उस कारण से टूट गए। –

+0

@mattMcNadd - गति के लिए समाधान केवल स्थिर होना है - यह एक ऐसा मामला है जहां प्रति प्रोसेसर आसान है। –

-1

यह आपके प्रश्न का सख्ती से जवाब नहीं है, लेकिन फिर भी आप इसे सहायक पा सकते हैं। यह पोर्टेबल नहीं है, लेकिन यदि आप इसे ग्लिबैक पर चला रहे हैं, तो आप इसके बजाय asprintf() का उपयोग कर सकते हैं, जो आपके लिए स्मृति आवंटन करेगा।

संबंधित मुद्दे