हां, यह printf
के सभी संस्करणों के साथ एक समस्या है जिसे मैं जानता हूं। मैं संक्षेप में इस मामले पर this answer और this one में चर्चा करता हूं।
सी के लिए, मुझे पुस्तकालय की जानकारी नहीं है जो आपके लिए यह करेगी, लेकिन अगर किसी के पास यह है, तो यह आईसीयू होगा।
पर्ल के लिए, आपको Unicode::GCString मॉड्यूल फॉर्म सीपीएएन का उपयोग प्रिंट कॉलम की संख्या की गणना करने के लिए एक यूनिकोड स्ट्रिंग लेना होगा। यह Unicode Standard Annex #11: East Asian Width खाते में आता है।
उदाहरण के लिए, कुछ कोड बिंदु 1 कॉलम लेते हैं और अन्य 2 कॉलम लेते हैं। ऐसे कुछ भी हैं जो पात्रों और अदृश्य नियंत्रण वर्णों को संयोजित करने की तरह कोई कॉलम नहीं लेते हैं। कक्षा में columns
विधि है जो स्ट्रिंग को कितनी कॉलम लेती है।
मेरे पास यूनिकोड टेक्स्ट लंबवत here संरेखित करने के लिए इसका उपयोग करने का एक उदाहरण है। यह यूनिकोड स्ट्रिंग्स का एक गुच्छा सॉर्ट करेगा, जिसमें कुछ वर्ण और "चौड़े" एशियाई विचारधारा (सीजेके पात्र) संयोजन शामिल हैं, और आपको चीजों को लंबवत रूप से संरेखित करने की अनुमति देते हैं। थोड़ा umenu
डेमो प्रोग्राम है जो प्रिंट कि अच्छी तरह से उत्पादन गठबंधन, नीचे शामिल किया गया है के लिए
कोड।
आपको शायद अधिक महत्वाकांक्षी Unicode::LineBreak मॉड्यूल में रुचि हो सकती है, जिसमें उपर्युक्त Unicode::GCString
कक्षा केवल एक छोटा घटक है। यह मॉड्यूल बहुत कूलर है, और Unicode Standard Annex #14: Unicode Line Breaking Algorithm खाते में आता है।
पर्ल v5 पर परीक्षण किए गए छोटे umenu
डेमो के लिए कोड यहां दिया गया है।14:
#!/usr/bin/env perl
# umenu - demo sorting and printing of Unicode food
#
# (obligatory and increasingly long preamble)
#
use utf8;
use v5.14; # for locale sorting
use strict;
use warnings;
use warnings qw(FATAL utf8); # fatalize encoding faults
use open qw(:std :utf8); # undeclared streams in UTF-8
use charnames qw(:full :short); # unneeded in v5.16
# std modules
use Unicode::Normalize; # std perl distro as of v5.8
use List::Util qw(max); # std perl distro as of v5.10
use Unicode::Collate::Locale; # std perl distro as of v5.14
# cpan modules
use Unicode::GCString; # from CPAN
# forward defs
sub pad($$$);
sub colwidth(_);
sub entitle(_);
my %price = (
"γύρος" => 6.50, # gyros, Greek
"pears" => 2.00, # like um, pears
"linguiça" => 7.00, # spicy sausage, Portuguese
"xoriço" => 3.00, # chorizo sausage, Catalan
"hamburger" => 6.00, # burgermeister meisterburger
"éclair" => 1.60, # dessert, French
"smørbrød" => 5.75, # sandwiches, Norwegian
"spätzle" => 5.50, # Bayerisch noodles, little sparrows
"包子" => 7.50, # bao1 zi5, steamed pork buns, Mandarin
"jamón serrano" => 4.45, # country ham, Spanish
"pêches" => 2.25, # peaches, French
"シュークリーム" => 1.85, # cream-filled pastry like éclair, Japanese
"막걸리" => 4.00, # makgeolli, Korean rice wine
"寿司" => 9.99, # sushi, Japanese
"おもち" => 2.65, # omochi, rice cakes, Japanese
"crème brûlée" => 2.00, # tasty broiled cream, French
"fideuà" => 4.20, # more noodles, Valencian (Catalan=fideuada)
"pâté" => 4.15, # gooseliver paste, French
"お好み焼き" => 8.00, # okonomiyaki, Japanese
);
my $width = 5 + max map { colwidth } keys %price;
# So the Asian stuff comes out in an order that someone
# who reads those scripts won't freak out over; the
# CJK stuff will be in JIS X 0208 order that way.
my $coll = new Unicode::Collate::Locale locale => "ja";
for my $item ($coll->sort(keys %price)) {
print pad(entitle($item), $width, ".");
printf " €%.2f\n", $price{$item};
}
sub pad($$$) {
my($str, $width, $padchar) = @_;
return $str . ($padchar x ($width - colwidth($str)));
}
sub colwidth(_) {
my($str) = @_;
return Unicode::GCString->new($str)->columns;
}
sub entitle(_) {
my($str) = @_;
$str =~ s{ (?=\pL)(\S) (\S*) }
{ ucfirst($1) . lc($2) }xge;
return $str;
}
जैसा कि आप देख, यह है कि विशेष कार्यक्रम में काम करने के लिए कुंजी कोड, जो सिर्फ ऊपर परिभाषित अन्य कार्यों कॉल की इस पंक्ति है, और मॉड्यूल मैं चर्चा कर रहा था का उपयोग करता है:
print pad(entitle($item), $width, ".");
वह भरने वाले चरित्र के रूप में डॉट्स का उपयोग करके दी गई चौड़ाई पर आइटम को पैड करेगा।
हां, यह printf
बहुत कम सुविधाजनक है, लेकिन कम से कम यह संभव है।
दूसरे शब्दों में, आप पर्ल और/या सी के लिए 'printf' के बहुविविध-जागरूक संस्करण की तलाश में हैं? – deceze
मैंने सी में utf8 डिकोडिंग कभी नहीं किया है लेकिन यहां एक गो कोड है जो एक utf-8 स्ट्रिंग में रनों की गणना करता है: http://golang.org/src/pkg/unicode/utf8/utf8.go?s=4824:4876 # एल 202 –
@dystroy यह केवल कोड बिंदुओं (यानी, रन) की गणना करने की बात नहीं है। इसके बजाय, यह ध्यान में रख रहा है कि विभिन्न कोड बिंदु प्रति UAX # 11 प्रति 0, 1, या 2 प्रिंट कॉलम का प्रतिनिधित्व करते हैं, और यह काफी सूक्ष्म है, खासकर 'East_Asian_Width = अस्पष्ट' वर्णों के साथ। मुझे किसी भी गो लाइब्रेरी के बारे में पता नहीं है, जिस तरह से मेरे उत्तर में पर्ल लाइब्रेरी का वर्णन किया गया है, लेकिन यदि गो के लिए ऐसी कोई चीज है, तो मुझे इसके बारे में जानना अच्छा लगेगा! धन्यवाद। – tchrist