uint8_t কাউট দিয়ে মুদ্রণ করা যায় না


146

সি ++ তে পূর্ণসংখ্যার সাথে কাজ করার বিষয়ে আমার একটি অদ্ভুত সমস্যা রয়েছে।

আমি একটি সাধারণ প্রোগ্রাম লিখেছিলাম যা একটি ভেরিয়েবলের মান নির্ধারণ করে এবং তারপরে এটি মুদ্রণ করে তবে এটি প্রত্যাশার মতো কাজ করছে না।

আমার প্রোগ্রামে কোডের দুটি মাত্র লাইন রয়েছে:

uint8_t aa = 5;

cout << "value is " << aa << endl;

এই প্রোগ্রামের আউটপুট হয় value is

অর্থাৎ এটি খালি প্রিন্ট করে aa

যখন আমি পরিবর্তন uint8_tকরতে uint16_tউপরের কোড একটি যাদুমন্ত্র মত কাজ করে।

আমি উবুন্টু 12.04 (যথার্থ প্যাঙ্গোলিন), 64-বিট এবং আমার সংকলক সংস্করণটি ব্যবহার করি:

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)


উত্তর:


150

এটি সত্যিই একটি ফাঁকা মুদ্রণ করে না, তবে সম্ভবত মান 5 সহ ASCII অক্ষর, যা মুদ্রণযোগ্য (বা অদৃশ্য)। এখানে অনেকগুলি অদৃশ্য ASCII অক্ষর কোড রয়েছে , যার মধ্যে বেশিরভাগের মান 32 এর নীচে, যা আসলে ফাঁকা।

আপনাকে দৃশ্যমান অক্ষর মানের আউটপুট দেওয়ার চেষ্টা করার কারণে আপনাকে সংখ্যার মান আউটপুটতে রূপান্তর aaকরতে unsigned intহবে ostream& operator<<(ostream&, unsigned char)

uint8_t aa=5;

cout << "value is " << unsigned(aa) << endl;

24
যেহেতু সি স্টাইলের কাস্টগুলিতে উদ্দীপনা রয়েছে, তাই স্ট্যাটিক_কাস্ট করা কি ভাল হবে না?
টিম সেগুইন

37
এটি রূপান্তর করা উচিত int। Castালাই এটি করার এক উপায়, তবে একমাত্র উপায় নয়। +aaকাজ করে।
পিট বেকার 14

5
int (var) এবং (int) var আসলে একই জিনিস নয়?
পলম

9
টাইপ (ভার) ব্যবহার করে লিঙ্কযুক্ত প্রশ্নটি (টাইপ) ভেরর সাথে তার সি কাস্টের মতো একই - কনস্ট ইত্যাদি দিয়ে চেষ্টা করে দেখুন, এটি সরিয়ে দেয়!
পলম

13
প্রতিক্রিয়া "নং সি-স্টাইলের ক্যাসেটগুলি বেশ কয়েকটি কারণে সি ++ এর জন্য নিরুৎসাহিত করা হয়েছে।" "" int (var) এবং (int) var আসলে একই জিনিস নয়? " নিশ্চিতভাবে এটি মনে হয় যেন আপনি বুঝতে পারেন নি int(var)এবং (int)varঠিক একই অর্থ রয়েছে। ঠিক একই কারণে int(var)যেখানে সেই পরিস্থিতিতে হতাশ হয় (int)var, কারণ এর অর্থ হুবহু একই জিনিস। (আমি বুঝতে পারি কেন আপনি যেভাবে যাইহোক এটির জন্য এখানে কেন যেতে চাই, তবে আমি আপনাকে এটির ব্যবহার করার দরকার বলছি না static_castjust আমি কেবলমাত্র মনে করি মন্তব্য মন্তব্যটি এখানে কিছুটা অযৌক্তিকভাবে বিভ্রান্ত পেয়েছে))

46

uint8_tসম্ভবত একটি typedefজন্য হবে unsigned charostreamবর্গ জন্য একটি বিশেষ জমিদার হয়েছে unsigned char, IE এটা সংখ্যা 5, যা মুদ্রণযোগ্য নয় এমন হয়, অত: পর খালি স্থান সঙ্গে চরিত্র ছাপে।


14
আমি স্ট্যান্ডার্ডটি সত্যিই স্ট্যান্ড :: uint8_t কে একটি পৃথক ধরণের হিসাবে চিকিত্সা করতে চাই এবং কেবল একটি ফ্রিগিন টাইপইফ নয় wish যখন স্ট্রিম অবজেক্টের সাথে একযোগে ব্যবহৃত হয় তখন এই ধরণের চরিত্র-শব্দার্থ প্রয়োগের কোনও বুদ্ধিমান কারণ নেই।
antred

37

যে কোনও আদিম ডাটা টাইপের ভেরিয়েবলের আগে একটি অ্যানারি + অপারেটর যুক্ত করা এএসসিআইআই অক্ষরের পরিবর্তে মুদ্রণযোগ্য সংখ্যার মান দেবে (চরের ধরণের ক্ষেত্রে)।

uint8_t aa = 5;
cout<<"value is "<< +aa <<endl;

এটি দুর্দান্ত, তবে সি ++ কেন সংখ্যার মান uint8_tহিসাবে unsigned charবিবেচিত হবে না?
R1S8K

@ আর 1 এস 8 কে এটি হ'ল কারণ uint8_tএটি কেবলমাত্র একটি টাইপ ডিএফ unsigned char, unsigned charনিজেই ostreamঠিক পছন্দ মতো পরিচালিত হয় charএবং এর ASCII মান মুদ্রণ করে।
হর্ষ

@ হর্ষ ধন্যবাদ মানুষ! সুতরাং এটি একটি টাইপ ডিএফ unsigned charঅনেক ব্যাখ্যা করে। সুতরাং একমাত্র পূর্ণসংখ্যা int, তাই না ?
এস

@ আর 1 এস 8 কে ভাল, সবচেয়ে ছোট পূর্ণসংখ্যার ধরণটি short int2 বাইট লাগবে। পাশাপাশি পূর্ণসংখ্যার ধরণের আরও কয়েকটি ভিন্নতা রয়েছে।
হর্ষ

@ হর্ষ এছাড়াও আমি মনে করি যখন প্রোগ্রামিং এবং ভেরিয়েবলগুলি ঘোষণা করার সময়, আমি কোনও ভেরিয়েবল ঘোষণা করি তাতে কিছু আসে যায় না যে কেবলমাত্র ছোট সংখ্যার সাথেই যেমন একটি বড় রেজিস্টার আকারের সাথে 250 এর বেশি না হয় longবা intসংকলকটি র‌্যাম বা ফ্ল্যাশের ব্যবহারকে অনুকূল করে তুলবে এই নিবন্ধটি পূরণ করে কি অনুযায়ী, আমি ঠিক আছি?
এস 8 কে

16

এর কারণ আউটপুট অপারেটর একটির uint8_tমতো আচরণ করে char( uint8_tসাধারণত এটি কেবলমাত্র একটি উপনাম unsigned char), সুতরাং এটি ASCII কোড (যা সর্বাধিক সাধারণ চরিত্রের এনকোডিং সিস্টেম) দ্বারা অক্ষর মুদ্রণ করে 5

উদাহরণস্বরূপ দেখুন এই রেফারেন্স


কেন? সি সংকলক এটি একটি সংখ্যা হিসাবে বিবেচনা করে। আমি মনে করি সি ++ এই মুহুর্তে আলাদা।
এস

@ পার্চএগল আপনি লিঙ্কযুক্ত রেফারেন্সটি পড়লে দেখতে পাবেন অপারেটর উভয় signedএবং unsignedঅক্ষরের জন্যই ওভারলোড হয়েছে ( charসি ++ এর মধ্যে যা সত্যিই তৃতীয় পৃথক প্রকারের সমতল )। সুতরাং যদি (খুব সম্ভবত) এর uint8_tজন্য কোনও এলিফ থাকে তবে এটি unsigned charব্যবহার করা হবে।
কিছু প্রোগ্রামার বাবু

আপনি কি এই থ্রেডটিতে আমার উত্তরটি পরীক্ষা করতে পারেন এবং আমার উত্তরটি সঠিক কিনা তা আমাকে বলতে পারেন? stackoverflow.com/questions/15585267/… , আমার উত্তর শেষের আগে is তোমাকে অনেক ধন্যবাদ.
R1S8K

14
  • ব্যবহারের মেকিং ADL (আর্গুমেন্ট-নির্ভরশীল নাম লুকআপ):

    #include <cstdint>
    #include <iostream>
    #include <typeinfo>
    
    namespace numerical_chars {
    inline std::ostream &operator<<(std::ostream &os, char c) {
        return std::is_signed<char>::value ? os << static_cast<int>(c)
                                           : os << static_cast<unsigned int>(c);
    }
    
    inline std::ostream &operator<<(std::ostream &os, signed char c) {
        return os << static_cast<int>(c);
    }
    
    inline std::ostream &operator<<(std::ostream &os, unsigned char c) {
        return os << static_cast<unsigned int>(c);
    }
    }
    
    int main() {
        using namespace std;
    
        uint8_t i = 42;
    
        {
            cout << i << endl;
        }
    
        {
            using namespace numerical_chars;
            cout << i << endl;
        }
    }

    আউটপুট:

    *
    42
  • একটি কাস্টম স্ট্রিম ম্যানিপুলেটরও সম্ভব হবে।

  • অ্যানারি প্লাস অপারেটর খুব ঝরঝরে প্রতিমা ( cout << +i << endl)।

8
নয় চুম্বন এখনও একটি বৈধ দৃষ্টান্ত ??
πάντα ῥεῖ


4
@ πάνταῥεῖ ঠিক আছে, তখন সি ++ কোডে কয়েক ধরণের সি স্টাইলের ক্যাসেটগুলি চালিয়ে যান, যে কেউ পরিবেশে যেভাবে সে সবচেয়ে বেশি ফিট করে সেভাবে উত্পাদনশীল হতে পারে।
মরিচ_চিকো

5
@ πάνταῥεῖ সিরিয়াসলি? ফাংশনাল স্টাইলের কাস্ট, কেবল সি স্টাইল কাস্টিং। অন্যের থেকে একটি পরিবর্তন করা সি এর ক্ষেত্র ছেড়ে যাওয়ার কোনও কাজে সহায়তা করে না, চেক করুন: stackoverflow.com/a/4775807/1000282 । পিট-বেকার আপনার উত্তরটিতেও এটি মন্তব্য করেছে তবে আপনি তাঁর শেষ মন্তব্যটি মিস করেছেন বলে মনে হয়।
মরিচ_চিকো

3
এই সমাধানটি খুব মার্জিত এবং কার্যকর, কারণ এটি টেমপ্লেটগুলির সাথে কাজ করে। সত্যিকার অর্থে, আমি এটিই সমাধান করেছি যে এটি আমার জন্য কাজ করে। যদিও একটি সতর্কতামূলকভাবে, প্রথম ফাংশনটিতে একটি বাগ রয়েছে, কারণ 'ওএস' একক প্রকারের সাথে আবদ্ধ, এবং তাই স্বাক্ষরিত বা স্বাক্ষরযুক্ত মান অপারেটরের ভুল সংস্করণে প্রেরণ করা হবে << ()। return std::is_signed<char>::value ? os << static_cast<int>(c) : os << static_cast<unsigned int>(c);
জর্জেস 21


4

operator<<()মধ্যে জমিদার istreamএবং charএকটি অ-সদস্য ফাংশন। আপনি স্পষ্টভাবে সদস্য ফাংশনটি কোনও char(বা ক uint8_t) হিসাবে হিসাবে ব্যবহার করতে পারেন int

#include <iostream>
#include <cstddef>

int main()
{
   uint8_t aa=5;

   std::cout << "value is ";
   std::cout.operator<<(aa);
   std::cout << std::endl;

   return 0;
}

আউটপুট:

value is 5

2

অন্যরা যেমন সমস্যাটি হওয়ার আগে বলেছিল কারণ স্ট্যান্ডার্ড স্ট্রিম স্বাক্ষরিত চর এবং স্বাক্ষরযুক্ত চরটিকে একক অক্ষর হিসাবে না সংখ্যা হিসাবে বিবেচনা করে।

এখানে ন্যূনতম কোড পরিবর্তনগুলির সাথে আমার সমাধানটি দেওয়া হয়েছে:

uint8_t aa = 5;

cout << "value is " << aa + 0 << endl;

যোগ "+0"করা ফ্লোটিং পয়েন্ট সহ যে কোনও সংখ্যার সাথে নিরাপদ।

পূর্ণসংখ্যা ধরনের এটি ফলাফলের ধরণ পরিবর্তন করতে হবে intযদি sizeof(aa) < sizeof(int)। এবং এটি টাইপ পরিবর্তন হবে না যদি sizeof(aa) >= sizeof(int)

এই সমাধানটি int8_tস্ট্রিমে মুদ্রণের জন্য প্রস্তুত করার জন্যও বেশ ভাল, অন্য কয়েকটি সমাধান এতটা ভাল না হলেও:

int8_t aa = -120;

cout << "value is " << aa + 0 << endl;
cout << "bad value is " << unsigned(aa) << endl;

আউটপুট:

value is -120
bad value is 4294967176

গোলমরিচ_চিকো দ্বারা প্রদত্ত এডিএল সহ পিএস সলিউশন এবং πάντα really সত্যই সুন্দর।

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