সি তে হেক্সাডেসিমাল অক্ষর মুদ্রণ করা হচ্ছে


104

আমি অক্ষরের একটি লাইনে পড়ার চেষ্টা করছি, তারপরে অক্ষরের সমান হেক্সাডেসিমাল মুদ্রণ করুন।

উদাহরণস্বরূপ, যদি আমার কাছে একটি স্ট্রিং থাকে "0xc0 0xc0 abc123"যেখানে প্রথম 2 টি অক্ষর c0হেক্সে থাকে এবং বাকী অক্ষরগুলি abc123ASCII এ থাকে তবে আমার পাওয়া উচিত

c0 c0 61 62 63 31 32 33

তবে, printfব্যবহার %xআমাকে দেয়

ffffffc0 ffffffc0 61 62 63 31 32 33

আমি ছাড়া আউটপুটটি কীভাবে পেতে চাই "ffffff"? এবং কেন এটি কেবল সি 0 (এবং 80) ffffffএর অন্যান্য অক্ষরগুলি নেই?


আপনার বাইটের অ্যারের সাথে মেলে এমন স্ট্রিংটি হবে ..."\xc0\xc0abc123"
বুড়ো

উত্তর:


134

আপনার সিস্টেমে স্বাক্ষরিত ffffffহওয়ায় আপনি এটি দেখতে পাচ্ছেন char। সি-তে, ভারার্গ ফাংশনগুলি যেমন printfসমস্ত সংখ্যাকে তার চেয়ে ছোট করে প্রচার intকরে int। যেহেতু charএকটি পূর্ণসংখ্যা (আপনার ক্ষেত্রে 8-বিট স্বাক্ষরিত পূর্ণসংখ্যার), তাই আপনার চরগুলি intসাইন-এক্সটেনশনের মাধ্যমে প্রচার করা হচ্ছে ।

যেহেতু c0এবং 80একটি শীর্ষস্থানীয় 1-বিট রয়েছে (এবং এটি 8-বিট পূর্ণসংখ্যা হিসাবে নেতিবাচক) তাই সেগুলি সাইন-প্রসারিত হচ্ছে যখন আপনার নমুনার অন্যরা না করে।

char    int
c0 -> ffffffc0
80 -> ffffff80
61 -> 00000061

এখানে একটি সমাধান:

char ch = 0xC0;
printf("%x", ch & 0xff);

এটি উপরের বিটগুলি মাস্ক করে দেবে এবং আপনার চেয়ে কম 8 টি বিট রাখবে।


15
Cast unsigned charালাই ব্যবহার করে আমার সমাধানটি x86-64 এর জন্য gcc4.6 এ একটি নির্দেশ ছোট ...
lvella

4
আমি সাহায্য করতেও পারি. এটি (প্রযুক্তিগতভাবে) অপরিজ্ঞাত আচরণ কারণ স্পেসিফায়ারকে xএকটি স্বাক্ষরবিহীন প্রকারের প্রয়োজন হয়, তবে সিএইচ ইনট হিসাবে প্রচার করা হয়। সঠিক কোড কেবল স্বাক্ষরবিহীন করার CH নিক্ষেপ, অথবা স্বাক্ষরবিহীন গৃহস্থালির কাজ এবং সুনির্দিষ্টভাবে উল্লেখ করা করার জন্য একটি ঢালাই ব্যবহার করুন: hhx
2501

4
আমার কাছে থাকলে printf("%x", 0)কিছুই মুদ্রিত হয় না।
গুস্তাভো মীরা

এটি কোনও কিছু মুদ্রণ করে না কারণ সর্বনিম্ন 0 এ সেট করা আছে এটি ঠিক করতে, চেষ্টা করুন printf("%.2x", 0);যা সর্বনিম্ন অক্ষরগুলিকে 2 এ টানবে boo একটি সংখ্যা সহ উদাহরণস্বরূপ, আপনি কেবল 2 অক্ষরকে আঁকতে বাধ্য করতে পারেনprintf("%2.2x", 0);
ব্যবহারকারী 2262111

@ নৃশংস_লোস্টার এর উত্তর হিসাবে printf("%x", ch & 0xff)ব্যবহারের চেয়ে কেন আরও ভাল হওয়া উচিত ? printf("%02hhX", a)
ম্যাক্সচলেপজিগ

62

প্রকৃতপক্ষে ইন-তে টাইপ রূপান্তর রয়েছে। এছাড়াও আপনি% hhx সুনির্দিষ্ট ব্যবহার করে চরকে টাইপ করতে বাধ্য করতে পারেন।

printf("%hhX", a);

বেশিরভাগ ক্ষেত্রে আপনি ন্যূনতম দৈর্ঘ্য নির্ধারণ করতে পাশাপাশি শূন্যের সাথে দ্বিতীয় অক্ষরটি পূরণ করতে চান:

printf("%02hhX", a);

আইএসও / আইইসি 9899: 201x বলেছেন:

7 দৈর্ঘ্য সংশোধক এবং এর অর্থ হ'ল: hh সুনির্দিষ্ট করে যে নিম্নলিখিত ডি, আই, ও, ইউ, এক্স, বা এক্স রূপান্তর নির্দিষ্টকরণটি একটি স্বাক্ষরিত চর বা স্বাক্ষরবিহীন চার্ট আর্গুমেন্টের জন্য প্রযোজ্য (আর্গুমেন্টটি পূর্ণসংখ্যা প্রচার অনুসারে প্রচার করা হবে, তবে এর মান মুদ্রণের আগে স্বাক্ষরিত চর বা স্বাক্ষরবিহীন চরে রূপান্তরিত হবে); বা এটি একটি নিম্নলিখিত


30

আপনি একটি স্বাক্ষরবিহীন চর তৈরি করতে পারেন:

unsigned char c = 0xc5;

এটি মুদ্রণ দিতে হবে C5এবং না ffffffc5

কেবল 127 এর চেয়ে বড় অক্ষরগুলি মুদ্রিত হয় ffffffকারণ তারা নেতিবাচক (চর স্বাক্ষরিত)।

অথবা আপনি charমুদ্রণের সময় কাস্ট করতে পারেন :

char c = 0xc5; 
printf("%x", (unsigned char)c);

4
প্রকৃত সেরা উত্তরটি +1 করুন, স্পষ্টত টাইপ করা যতটা সম্ভব ডেটা ঘোষণার নিকটে (তবে কাছাকাছি নয়)।
বব স্টেইন

13

আপনি সম্ভবত 0xc0 মান একটি charভেরিয়েবলে সংরক্ষণ করছেন , সম্ভবত কোনও স্বাক্ষরিত প্রকারটি কী এবং আপনার মানটি নেতিবাচক (সবচেয়ে গুরুত্বপূর্ণ বিট সেট)। তারপর যখন মুদ্রণ, এটা রূপান্তরিত হয় int, এবং semantical সমানতা, কম্পাইলার প্যাড 0xff সঙ্গে অতিরিক্ত বাইট রাখা, এত নেগেটিভ intআপনার নেতিবাচক একই সংখ্যাগত মান থাকবে char। এটি ঠিক করতে, unsigned charমুদ্রণের সময় কেবল কাস্ট করুন :

printf("%x", (unsigned char)variable);

13

আপনি hhবলতে পারেন printfযে আর্গুমেন্টটি স্বাক্ষরবিহীন চর। ব্যবহারের 0শূন্য প্যাডিং পেতে এবং 22. প্রস্থ সেট করতে xবা Xনিম্ন / বড় হাতের হেক্স অক্ষরের জন্য।

uint8_t a = 0x0a;
printf("%02hhX", a); // Prints "0A"
printf("0x%02hhx", a); // Prints "0x0a"

সম্পাদনা : যদি পাঠকরা 2501 এর এই বক্তব্য সম্পর্কে উদ্বিগ্ন হন যে এটি কোনওভাবেই 'সঠিক' ফর্ম্যাট স্পেসিফায়ার নয় তবে আমার পরামর্শ তারা আবার printfলিঙ্কটি পড়েন । বিশেষত:

যদিও% সি অন্তর্গঠনের প্রত্যাশা করে, ভেরিয়েডিক ফাংশন বলা হয়ে থাকে তখন পূর্ণসংখ্যা প্রচারের কারণে একটি চর পাস করা নিরাপদ।

নির্দিষ্ট প্রস্থের অক্ষরের ধরণের (ইন্ট 8_টি, ইত্যাদি) জন্য সঠিক রূপান্তরকরণের বিবরণগুলি শিরোনাম <cinttypes>(সি ++) বা <inttypes.h>(সি) (যদিও পিআরডিএমএক্স, পিআরইউম্যাক্স, ইত্যাদি% jd,% ju, ইত্যাদি) এর সমার্থক হিসাবে সংজ্ঞায়িত করা হয়েছে ।

স্বাক্ষরিত বনাম স্বাক্ষরিত সম্পর্কে তার বক্তব্য হিসাবে, এই ক্ষেত্রে মানগুলি সর্বদা ইতিবাচক হওয়া উচিত এবং স্বাক্ষরিত ইনটিতে সহজেই ফিট হওয়া উচিত। যাইহোক কোনও সাইনড হেক্সাইডেক্সিমাল ফর্ম্যাট নির্দিষ্টকারী নেই।

সম্পাদনা 2 : ("কখন-স্বীকার করবেন-আপনি-ভুল" সংস্করণ):

আপনি যদি 311 (পিডিএফের 329) পৃষ্ঠায় আসল সি 11 মানটি পড়েন তবে :

HH: নির্দিষ্ট করে যে একটি নিম্নলিখিত d, i, o, u, x, অথবা Xরূপান্তর উল্লেখ এই ক্ষেত্রে প্রযোজ্য signed charবা unsigned charযুক্তি (যুক্তি পূর্ণসংখ্যা প্রচার অনুযায়ী উন্নীত হবে করা হয়েছে, কিন্তু এর মান রূপান্তরিত হইবে signed charবা unsigned charপ্রিন্ট করার পূর্বে); বা নিম্নলিখিত nরূপান্তর নির্দিষ্টকরণকারীর একটি signed charযুক্তি একটি পয়েন্টার উপর প্রযোজ্য ।


Uint8_t টাইপের জন্য নির্দিষ্টকরণগুলি সঠিক নয়। নির্দিষ্ট প্রস্থের প্রকারগুলি বিশেষ প্রিন্ট স্পেসিফায়ার ব্যবহার করে। দেখুন:inttypes.h
2501

হ্যাঁ তবে সমস্ত ভ্যারাগস পূর্ণসংখ্যাকে অন্তর্নিহিতভাবে ইনট হিসাবে প্রচার করা হয়।
টিম্ম্ম্ম

এটি হতে পারে তবে সি হিসাবে সংজ্ঞায়িত হিসাবে, আপনি যদি সঠিক নির্দিষ্টকারক ব্যবহার না করেন তবে আচরণটি অপরিজ্ঞাত।
2501

কিন্তু% এক্স হয় সঠিক সুনির্দিষ্টভাবে উল্লেখ করা। ( charএবং unsigned charউন্নীত করা হয় int) [ en.cppreference.com/w/cpp/language/variadic_arguments] । আপনার প্ল্যাটফর্মে ফিট না হওয়া বিষয়গুলির জন্য আপনাকে কেবল পিআরআই স্পেসিফায়ার ব্যবহার করতে হবে int- যেমন unsigned int
টিমম্মে

%xস্বাক্ষরযুক্ত না int জন্য সঠিক। প্রকার চর এবং স্বাক্ষরবিহীন চরকে ইনট হিসাবে প্রচার করা হয়। এছাড়াও uint8_t স্বাক্ষরবিহীন চর হিসাবে সংজ্ঞায়িত হওয়ার কোনও গ্যারান্টি নেই।
2501

2

আপনি সম্ভবত একটি স্বাক্ষরিত চর অ্যারে থেকে মুদ্রণ করছেন। হয় স্বাক্ষরবিহীন চর অ্যারে থেকে মুদ্রণ করুন বা 0xff সহ মানটি মাস্ক করুন: যেমন ar [i] এবং 0xFF। উচ্চ (চিহ্ন) বিট সেট হওয়ার কারণে সি0 মানগুলি সাইন বাড়ানো হচ্ছে।


0

এরকম কিছু চেষ্টা করুন:

int main()
{
    printf("%x %x %x %x %x %x %x %x\n",
        0xC0, 0xC0, 0x61, 0x62, 0x63, 0x31, 0x32, 0x33);
}

যা এটি উত্পাদন করে:

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