2016-02-16 7 views
5

मैं चौड़ाई विनिर्देशक और printf-समारोह के साथ ग में कुछ तार के उत्पादन में स्वरूपित करने के लिए कोशिश कर रहा हूँ के साथ ठीक से काम नहीं करता। हालांकि मुझे जो व्यवहार चाहिए वह मुझे परेशानी हो रही है। ऐसा लगता है कि प्रत्येक बार printf चरित्र को सामना करता है, या एक स्ट्रिंग के लिए आरक्षित चौड़ाई एक स्थिति छोटी हो जाती है।printf में चौड़ाई विनिर्देशक उच्चारण चिह्न वर्ण

एक कोड-टुकड़ा वर्णन करने के लिए:

#include <stdio.h> 

int main(void) 
{ 
    printf(">%-10s<\n", "aoa"); 
    printf(">%-10s<\n", "aäoa"); 
    printf(">%-10s<\n", "aäoöa"); 
    printf(">%-10s<\n", "aäoöaå"); 

    return 0; 
} 

आउटपुट मेरी ubuntu linux bash-खोल में।

>aoa  < 
>aäoa  < 
>aäoöa < 
>aäoöaå < 

मैं इस से निपटने के तरीके पर सलाह ले रहा हूं।

>aoa  < 
>aäoa  < 
>aäoöa  < 
>aäoöaå < 

मैं भी क्यों यह हो रहा या प्रतिक्रिया है के बारे में कोई अंतर्दृष्टि की सराहना करता है, तो यह एक नहीं है: क्या मैं चाहता हूँ ऊपर स्निपेट में सभी स्ट्रिंग्स इसलिए की तरह अंतरिक्ष गद्देदार 10 चार व्यापक क्षेत्र के भीतर मुद्रित करने के लिए के लिए है अन्य सेटअप के साथ मुद्दा।

+0

क्या आप यूटीएफ -8 एन्कोडिंग का उपयोग कर रहे हैं? उन पात्रों को 2 बाइट की आवश्यकता होती है, और 'printf' यूटीएफ -8 को अवगत नहीं हो सकता है। – user694733

+1

http://stackoverflow.com/questions/15528359/printing-utf-8-strings-with-printf-wide-vs-multibyte-string-literals – 123

+0

@ user694733 हां, मैं utf-8 –

उत्तर

4

क्यों यह हो रहा है?

विस्तृत वर्ण के लिए और UTF8 के तहत एक विकल्प के रूप The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets

को एक नजर डालें, तो आप गैर- ASCII वर्ण की संख्या की गणना करने के लिए इस सुविधा का उपयोग कर सकते हैं, तो, आप परिणाम की चौड़ाई विनिर्देशक को जोड़ सकते हैं printf:

#include <stdio.h> 

int func(const char *str) 
{ 
    int len = 0; 

    while (*str != '\0') { 
     if ((*str & 0xc0) == 0x80) { 
      len++; 
     } 
     str++; 
    } 
    return len; 
} 

int main(void) 
{ 
    printf(">%-*s<\n", 10 + func("aoa"), "aoa"); 
    printf(">%-*s<\n", 10 + func("aäoa"), "aäoa"); 
    printf(">%-*s<\n", 10 + func("aäoöa"), "aäoöa"); 
    printf(">%-*s<\n", 10 + func("aäoöaå"), "aäoöaå"); 
    return 0; 
} 

आउटपुट:

>aoa  < 
>aäoa  < 
>aäoöa  < 
>aäoöaå < 
+1

भले ही मुझे लगता है कि wprintf का उपयोग करना लंबे समय तक अधिक उचित है, मैं आपके सुझाव का उपयोग करके समाप्त हुआ। लिंक यह था। स्वीकृत के रूप में। –

6

उपयोग विस्तृत चरित्र तार और wprintf:

#include <cwchar> 
#include <locale.h> 

int main(void) 
{ 
    // seems to be needed for the correct output encoding 
    setlocale(LC_ALL, ""); 

    wprintf(L">%-10ls<\n", L"aoa"); 
    wprintf(L">%-10ls<\n", L"aäoa"); 
    wprintf(L">%-10ls<\n", L"aäoöa"); 
    wprintf(L">%-10ls<\n", L"aäoöaå"); 

    return 0; 
} 
+0

का उपयोग कर रहा था मैंने शाब्दिक तारों का उपयोग किया संक्षेप में रखने के लिए उदाहरण में। मेरी वास्तविक समस्या में मुझे स्ट्रिंग से तार मिल रहा है। मुझे लगता है कि मुझे इन तारों को [mbstowcs()] (http://linux.die.net/man/3/mbstowcs) या कुछ के साथ विस्तृत वर्ण-तारों में परिवर्तित करना होगा? मेरा मतलब है कि मैं स्पष्ट रूप से 'wprintf (एल ">% - 10ls <\n", Lsome-> सदस्य नहीं कर सकता);' –

2

Alter Mann's accepted answer, सही ढर्रे पर है, सिवाय इसके कि एक रों hould सिर्फ एक multibyte स्ट्रिंग में बाइट्स कि एक दृश्य चरित्र के लिए सांकेतिक शब्दों में बदलना नहीं है की संख्या की गणना के लिए एक कस्टम समारोह को हार्डकोड नहीं: आप स्ट्रिंग है जो नहीं है में बाइट्स की संख्या की गणना करने के लिए setlocale(LC_ALL, "") या इसी तरह की है, और strlen(str) - mbstowcs(NULL, str, 0) साथ कोड स्थानीय बनाना चाहिए एक दृश्य चरित्र एन्कोड करें।

setlocale() मानक सी है (C89, C99, C11), लेकिन यह भी POSIX.1 में परिभाषित किया। mbstowcs() मानक C99 और सी 11, और भी POSIX.1 में परिभाषित किया गया है। दोनों माइक्रोसॉफ्ट सी पुस्तकालयों में भी लागू किए गए हैं, इसलिए वे मूल रूप से हर जगह काम करते हैं।

निम्न उदाहरण कार्यक्रम, कि सी कमांड लाइन पर निर्दिष्ट स्ट्रिंग प्रिंट पर विचार करें:

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

/* Counts the number of (visible) characters in a string */ 
static size_t ms_len(const char *const ms) 
{ 
    if (ms) 
     return mbstowcs(NULL, ms, 0); 
    else 
     return 0; 
} 

/* Number of bytes that do not generate a visible character in a string */ 
static size_t ms_extras(const char *const ms) 
{ 
    if (ms) 
     return strlen(ms) - mbstowcs(NULL, ms, 0); 
    else 
     return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    int arg; 

    /* Default locale */ 
    setlocale(LC_ALL, ""); 

    for (arg = 1; arg < argc; arg++) 
     printf(">%-*s< (%zu bytes; %zu chars; %zu bytes extra in wide chars)\n", 
       (int)(10 + ms_extras(argv[arg])), argv[arg], 
       strlen(argv[arg]), ms_len(argv[arg]), ms_extras(argv[arg])); 

    return EXIT_SUCCESS; 
} 

आप example के लिए ऊपर संकलन है, और आप

./example aaa aaä aää äää aa€ a€€ €€€ a ä € 

कार्यक्रम होगा उत्पादन

चलाने
>aaa  < (3 bytes; 3 chars; 0 bytes extra in wide chars) 
>aaä  < (4 bytes; 3 chars; 1 bytes extra in wide chars) 
>aää  < (5 bytes; 3 chars; 2 bytes extra in wide chars) 
>äää  < (6 bytes; 3 chars; 3 bytes extra in wide chars) 
>aa€  < (5 bytes; 3 chars; 2 bytes extra in wide chars) 
>a€€  < (7 bytes; 3 chars; 4 bytes extra in wide chars) 
>€€€  < (9 bytes; 3 chars; 6 bytes extra in wide chars) 
>a   < (1 bytes; 1 chars; 0 bytes extra in wide chars) 
>ä   < (2 bytes; 1 chars; 1 bytes extra in wide chars) 
>€   < (3 bytes; 1 chars; 2 bytes extra in wide chars) 
>   < (4 bytes; 1 chars; 3 bytes extra in wide chars) 

यदि अंतिम < ऐसा करें तों अन्य लोगों के साथ नहीं मिलाया गया है क्योंकि प्रयुक्त फ़ॉन्ट सही ढंग से निश्चित-चौड़ाई नहीं है,:, इमोटिकॉन Ä की तरह सामान्य वर्णों से अधिक व्यापक है इतना ही है। फ़ॉन्ट को दोष दें।

अंतिम ओएस/ब्राउज़र/फ़ॉन्ट इसे प्रदर्शित नहीं कर सकता है, तो Emoticons unicode block से अंतिम चरित्र यू + 1 एफ 608 स्माइलिंग फेस है। लिनक्स में, सभी उपरोक्त > और < कंसोल (गैर-ग्राफिकल सिस्टम कंसोल) समेत सभी टर्मिनल में सही ढंग से लाइन अप करते हैं, हालांकि कंसोल फ़ॉन्ट में इमोटिकॉन के लिए ग्लिफ नहीं है, और इसके बजाय बस इसे एक हीरा।

Alter Mann's answer के विपरीत, यह दृष्टिकोण पोर्टेबल है, और इस बारे में कोई धारणा नहीं है कि वर्तमान उपयोगकर्ता द्वारा वास्तव में कौन सा चरित्र सेट उपयोग किया जाता है।

+0

अच्छा जवाब, आप पोर्टेबिलिटी के बारे में बिल्कुल सही हैं, मेरा कार्य यूटीएफ 8 मानता है। –

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