সি ++ এ 'প্রিন্টফ' বনাম 'কোট'


উত্তর:


332

আমি অবাক হয়েছি যে এই প্রশ্নের প্রত্যেকেই দাবি করেছে যে এটির std::coutচেয়ে ভাল printf, এমনকি যদি প্রশ্নটি কেবল ভিন্নতা চেয়েছিল। এখন, একটি পার্থক্য আছে - std::coutহয় C ++, ও printfসি (তবে, আপনি এটি C ++ ব্যবহার করতে পারেন, শুধু ভালো হয় প্রায় C থেকে অন্য কিছু)। এখন, আমি এখানে সৎ হব; উভয় printfএবং std::coutতাদের সুবিধা আছে।

বাস্তব পার্থক্য

extensibility

std::coutএক্সটেনসিবল আমি জানি যে লোকেরা printfএটিও এক্সটেনসিবল বলবে , তবে এই জাতীয় বর্ধনের কথা সি স্ট্যান্ডার্ডে উল্লেখ করা হয়নি (সুতরাং আপনাকে অ-মানক বৈশিষ্ট্যগুলি ব্যবহার করতে হবে - তবে সাধারণ অ-মানক বৈশিষ্ট্যটিও উপস্থিত নেই), এবং এই জাতীয় এক্সটেনশানগুলি একটি অক্ষর (সুতরাং ইতিমধ্যে বিদ্যমান ফর্ম্যাটটির সাথে দ্বন্দ্ব করা সহজ)।

বিপরীতে printf, std::coutঅপারেটর ওভারলোডিংয়ের উপর সম্পূর্ণ নির্ভর করে, তাই কাস্টম ফর্ম্যাটগুলির সাথে কোনও সমস্যা নেই - আপনারা যা করেন তা হ'ল std::ostreamপ্রথম আর্গুমেন্ট এবং দ্বিতীয় ধরণের হিসাবে আপনার টাইপ হিসাবে গ্রহণ করা একটি সাব্রোটিনকে সংজ্ঞায়িত করা । যেমন, কোনও নেমস্পেসের সমস্যা নেই - যতক্ষণ না আপনার ক্লাস থাকে (যা একটি চরিত্রের মধ্যে সীমাবদ্ধ নয়), আপনি std::ostreamএটির জন্য ওভারলোডিং কাজ করতে পারেন ।

যাইহোক, আমি সন্দেহ করি যে অনেক লোক প্রসারিত করতে চাইবে ostream(সত্য কথা বলতে, আমি খুব কমই এ জাতীয় এক্সটেনশানগুলি দেখেছি, যদিও তারা সহজ করা সহজ)। তবে আপনার প্রয়োজন হলে এটি এখানে।

বাক্য গঠন

এটিকে সহজে লক্ষ্য করা যায়নি, উভয় printfএবং std::coutবিভিন্ন সিনট্যাক্স ব্যবহার করুন। printfপ্যাটার্ন স্ট্রিং এবং পরিবর্তনশীল-দৈর্ঘ্যের আর্গুমেন্ট তালিকাগুলি ব্যবহার করে স্ট্যান্ডার্ড ফাংশন সিনট্যাক্স ব্যবহার করে। প্রকৃতপক্ষে, printfসি এগুলির একটি কারণ - printfফর্ম্যাটগুলি এগুলি ব্যতীত ব্যবহারের জন্য খুব জটিল। তবে, std::coutএকটি পৃথক এপিআই ব্যবহার করে - যে operator <<এপিআই নিজেই ফিরে আসে।

সাধারণত, এর অর্থ হ'ল সি সংস্করণটি ছোট হবে তবে বেশিরভাগ ক্ষেত্রে এটি কোনও ব্যাপার নয়। আপনি অনেক যুক্তি মুদ্রণ করার সময় পার্থক্যটি লক্ষণীয়। আপনার যদি Error 2: File not found.ত্রুটি নম্বরটি ধরে ধরে এর মতো কিছু লিখতে হয় এবং এর বিবরণ স্থানধারক হয় তবে কোডটি এর মতো দেখাবে। উভয় উদাহরণ অভিন্নভাবে কাজ করে (ভাল, সাজানোর, std::endlআসলে বাফার ফ্লাশ করে)।

printf("Error %d: %s.\n", id, errors[id]);
std::cout << "Error " << id << ": " << errors[id] << "." << std::endl;

এটি খুব পাগল হিসাবে প্রদর্শিত হবে না (এটি মাত্র দু'গুণ বেশি), যখন আপনি আসলে যুক্তিগুলি ছাপানোর পরিবর্তে আর্গুমেন্টগুলি ফর্ম্যাট করেন তখন জিনিসগুলি আরও বেশি পাগল হয়। উদাহরণস্বরূপ, এর মতো 0x0424কোনও কিছু প্রিন্ট করা কেবল উন্মাদ। এটি std::coutরাষ্ট্র এবং আসল মানগুলির মিশ্রণের কারণে ঘটে । আমি এমন কোন ভাষা দেখিনি যেখানে এর মতো কিছু std::setfillহ'ল টাইপ হবে (অবশ্যই সি ++ ব্যতীত)। printfযুক্তি এবং প্রকৃত প্রকারটি স্পষ্টভাবে পৃথক করে। আমি এর printfসংস্করণটির তুলনায় সত্যই এটির সংস্করণটি বজায় রাখতে পছন্দ করি (যদিও এটি ক্রিপ্টিক ধরনের মনে হয়) iostream(এটিতে খুব বেশি শব্দ রয়েছে)।

printf("0x%04x\n", 0x424);
std::cout << "0x" << std::hex << std::setfill('0') << std::setw(4) << 0x424 << std::endl;

অনুবাদ

এখানেই printfমিথ্যার আসল সুবিধা । printfফরম্যাট স্ট্রিং ভাল একটি স্ট্রিং ...। এটির operator <<অপব্যবহারের তুলনায় অনুবাদ করা সত্যই সহজ করে তোলে iostream। ধরে নিই যে gettext()ফাংশনটি অনুবাদ করে এবং আপনি দেখাতে চান Error 2: File not found., পূর্ববর্তী দেখানো ফর্ম্যাট স্ট্রিংয়ের অনুবাদ পেতে কোডটি দেখতে এরকম হবে:

printf(gettext("Error %d: %s.\n"), id, errors[id]);

এখন, ধরে নেওয়া যাক আমরা ফিকশনিশে অনুবাদ করি, যেখানে বর্ণনার পরে ত্রুটি সংখ্যাটি রয়েছে। অনুবাদকৃত স্ট্রিংয়ের মতো দেখতে হবে %2$s oru %1$d.\n। এখন, এটি সি ++ এ কীভাবে করবেন? ঠিক আছে, আমার কোনও ধারণা নেই। আমি অনুমান করি আপনি জাল তৈরি করতে পারেন iostreamযা অনুবাদ বা আপনি কিছু অনুবাদ printfকরতে পারেন gettextpurposes অবশ্যই, $সি স্ট্যান্ডার্ড নয়, তবে এটি এত সাধারণ যে এটি আমার মতে ব্যবহার করা নিরাপদ।

নির্দিষ্ট পূর্ণসংখ্যার টাইপ সিনট্যাক্সটি মনে রাখতে / দেখার প্রয়োজন নেই

সি এর অনেকগুলি পূর্ণসংখ্যার প্রকার রয়েছে, এবং সি ++ রয়েছে। std::coutহ্যান্ডলগুলি আপনার জন্য সব ধরনের, যখন printfএকটি পূর্ণসংখ্যা ধরনের উপর নির্ভর করে নির্দিষ্ট সিনট্যাক্স প্রয়োজন (সেখানে অ পূর্ণসংখ্যা ধরনের হয়, কিন্তু শুধুমাত্র অ পূর্ণসংখ্যা টাইপ আপনার সাথে বাস্তবে ব্যবহার করবে printfহয় const char *(গ স্ট্রিং, ব্যবহার প্রাপ্ত করা যাবে to_cপদ্ধতি std::string))। উদাহরণস্বরূপ, মুদ্রণের জন্য size_t, আপনাকে ব্যবহার করতে হবে %zd, যখন ব্যবহারের প্রয়োজন int64_tহবে %"PRId64"। টেবিলগুলি http://en.cppreferences.com/w/cpp/io/c/fprintf এবং http://en.cppreferences.com/w/cpp/tyype/integer এ উপলব্ধ ।

আপনি NUL বাইট মুদ্রণ করতে পারবেন না, \0

যেহেতু printfসি স্ট্রিংগুলি সি ++ স্ট্রিংয়ের বিপরীতে ব্যবহার করে, এটি নির্দিষ্ট কৌশল ছাড়া NUL বাইট মুদ্রণ করতে পারে না। নির্দিষ্ট ক্ষেত্রে এটি ব্যবহার করা সম্ভব %cসঙ্গে '\0', একটি আর্গুমেন্ট হিসাবে যদিও যে স্পষ্টতই হ্যাক করে।

পার্থক্য কেউ যত্ন করে না

কর্মক্ষমতা

আপডেট করুন: এটা পরিনত হয় যে iostream, তাই ধীর এটি সাধারণত ধীর আপনার হার্ড ড্রাইভে চেয়ে এর (আপনি ফাইলে আপনার প্রোগ্রাম পুনর্নির্দেশ থাকেন)। stdioআপনার যদি প্রচুর ডেটা আউটপুট প্রয়োজন হয় তবে এর সাথে সিঙ্ক্রোনাইজেশন অক্ষম করা সহায়তা করতে পারে। যদি পারফরম্যান্সটি সত্যিকারের উদ্বেগ হয় তবে (STDOUT- এ কয়েকটি লাইন লেখার বিপরীতে), কেবল ব্যবহার করুন printf

প্রত্যেকেই মনে করে যে তারা পারফরম্যান্সের বিষয়ে যত্নশীল, তবে কেউ এটি পরিমাপ করতে বিরক্ত করে না। আমার উত্তর হ'ল I / O যাই হোক বাধা হ'ল, আপনি ব্যবহার করেন printfবা না কেন, তা গুরুত্বপূর্ণ নয় iostream। আমি মনে করি এটি সমাবেশে তাত্ক্ষণিকভাবে দেখার চেয়ে দ্রুততর printf হতে পারে ( -O3সংকলক বিকল্পটি ব্যবহার করে ঝাঁকুনির সাহায্যে সংকলিত )। আমার ত্রুটির উদাহরণ হিসাবে ধরে নেওয়া, printfউদাহরণ উদাহরণের চেয়ে কম কল করে cout। এটি int mainসঙ্গে printf:

main:                                   @ @main
@ BB#0:
        push    {lr}
        ldr     r0, .LCPI0_0
        ldr     r2, .LCPI0_1
        mov     r1, #2
        bl      printf
        mov     r0, #0
        pop     {lr}
        mov     pc, lr
        .align  2
@ BB#1:

আপনি সহজেই লক্ষ্য করতে পারেন যে দুটি স্ট্রিং এবং 2(সংখ্যা) printfআর্গুমেন্ট হিসাবে চাপানো হয়েছে। এটা সম্বন্ধে; আর কিছুই নেই। তুলনার জন্য, এটি iostreamসমাবেশে সংকলিত হয়। না, কোন ইনলাইনিং নেই; প্রতিটি একক operator <<কল মানেই অন্য একটি যুক্তি যুক্ত সেট call

main:                                   @ @main
@ BB#0:
        push    {r4, r5, lr}
        ldr     r4, .LCPI0_0
        ldr     r1, .LCPI0_1
        mov     r2, #6
        mov     r3, #0
        mov     r0, r4
        bl      _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
        mov     r0, r4
        mov     r1, #2
        bl      _ZNSolsEi
        ldr     r1, .LCPI0_2
        mov     r2, #2
        mov     r3, #0
        mov     r4, r0
        bl      _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
        ldr     r1, .LCPI0_3
        mov     r0, r4
        mov     r2, #14
        mov     r3, #0
        bl      _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
        ldr     r1, .LCPI0_4
        mov     r0, r4
        mov     r2, #1
        mov     r3, #0
        bl      _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
        ldr     r0, [r4]
        sub     r0, r0, #24
        ldr     r0, [r0]
        add     r0, r0, r4
        ldr     r5, [r0, #240]
        cmp     r5, #0
        beq     .LBB0_5
@ BB#1:                                 @ %_ZSt13__check_facetISt5ctypeIcEERKT_PS3_.exit
        ldrb    r0, [r5, #28]
        cmp     r0, #0
        beq     .LBB0_3
@ BB#2:
        ldrb    r0, [r5, #39]
        b       .LBB0_4
.LBB0_3:
        mov     r0, r5
        bl      _ZNKSt5ctypeIcE13_M_widen_initEv
        ldr     r0, [r5]
        mov     r1, #10
        ldr     r2, [r0, #24]
        mov     r0, r5
        mov     lr, pc
        mov     pc, r2
.LBB0_4:                                @ %_ZNKSt5ctypeIcE5widenEc.exit
        lsl     r0, r0, #24
        asr     r1, r0, #24
        mov     r0, r4
        bl      _ZNSo3putEc
        bl      _ZNSo5flushEv
        mov     r0, #0
        pop     {r4, r5, lr}
        mov     pc, lr
.LBB0_5:
        bl      _ZSt16__throw_bad_castv
        .align  2
@ BB#6:

যাইহোক, সত্যি কথা বলতে, এর অর্থ কিছুই নেই, কারণ I / O যাই হোক বাধা। আমি কেবল এটি দেখাতে চেয়েছিলাম যে iostreamএটি দ্রুত নয় কারণ এটি "প্রকারের নিরাপদ"। বেশিরভাগ সি বাস্তবায়নগুলি printfগণিত গোটো ব্যবহার করে ফর্ম্যাটগুলি বাস্তবায়িত করে, তাই printfকম্পাইলার সম্পর্কে অবহিত printfনা হওয়া সত্ত্বেও এটি দ্রুততর হতে পারে (কোনও সংকলক printfনির্দিষ্ট ক্ষেত্রে অপ্টিমাইজ করতে পারে - ধ্রুব স্ট্রিংয়ের সমাপ্তি \nসাধারণত অনুকূলিত হয় puts) ।

উত্তরাধিকার

আপনি কেন উত্তরাধিকারী হতে চান ostreamতা আমি জানি না, তবে আমি যত্ন করি না। এটাও সম্ভব FILE

class MyFile : public FILE {}

সুরক্ষা টাইপ করুন

সত্য, পরিবর্তনশীল দৈর্ঘ্যের আর্গুমেন্ট তালিকার কোনও সুরক্ষা নেই, তবে এটি গুরুত্বপূর্ণ নয়, কারণ জনপ্রিয় সি সংকলকগণ printfযদি আপনি সতর্কতা সক্ষম করেন তবে ফর্ম্যাট স্ট্রিংয়ের সাথে সমস্যাগুলি সনাক্ত করতে পারে । আসলে, ক্ল্যাং সতর্কতা সক্ষম না করে এটি করতে পারে।

$ cat safety.c

#include <stdio.h>

int main(void) {
    printf("String: %s\n", 42);
    return 0;
}

$ clang safety.c

safety.c:4:28: warning: format specifies type 'char *' but the argument has type 'int' [-Wformat]
    printf("String: %s\n", 42);
                    ~~     ^~
                    %d
1 warning generated.
$ gcc -Wall safety.c
safety.c: In function main’:
safety.c:4:5: warning: format ‘%s expects argument of type char *’, but argument 2 has type int [-Wformat=]
     printf("String: %s\n", 42);
     ^

18
আপনি বলছেন যে আই / ও হ'ল যাই হোক বাধা। স্পষ্টতই আপনি কখনই সেই অনুমানটি পরীক্ষা করেননি আমি নিজেকে উদ্ধৃত করেছি: "অন্যদিকে, আইওস্ট্রিম সংস্করণ, 75.3 এমবি / সেকেন্ডে, হার্ড ডিস্কটি ধরে রাখার জন্য যথেষ্ট দ্রুত ডেটা বাফার করতে পারে না That's এটি খারাপ, এবং এটি এখনও কোনও বাস্তব কাজ করছে না I আমি ডন আমি যখন বলি আমার / ও লাইব্রেরিটি আমার ডিস্ক নিয়ামককে পূরণ করতে সক্ষম হবেন তখন আমার খুব বেশি প্রত্যাশা রয়েছে বলে মনে হয় না ""
বেন ভয়েগট

4
@ বেনভয়েগ: আমি স্বীকার করি, সম্ভব হলে আমি সি ++ এড়াতে চেষ্টা করি। আমি এটি অনেকটা ব্যবহার করার চেষ্টা করেছি, তবে এটি ছিল আরও বিরক্তিকর, এবং আমি ব্যবহৃত অন্যান্য প্রোগ্রামিং ভাষার চেয়ে কম রক্ষণাবেক্ষণযোগ্য। এটি আমার কাছে সি ++ এড়ানোর আরও একটি কারণ - এটি এমনকি দ্রুত নয় (এটি এমনকি আইস্ট্রিমও নয় - পুরো সি ++ লাইব্রেরি বেশিরভাগ বাস্তবায়নে ধীর, সম্ভবত ব্যতিক্রম ছাড়া std::sort, যা কোনওভাবে আশ্চর্যজনকভাবে qsort(2 বার) এর তুলনায় দ্রুততর হয় ) নির্বাহযোগ্য আকারের ব্যয়)।
কনরাড বোরোস্কি

3
কাউট ব্যবহার করার সময় এখানে কেউ সমান্তরাল পরিবেশে সমস্যাগুলি উল্লেখ করেনি।
নিকোলাস হ্যামিল্টন

9
আপনার পারফরম্যান্স যুক্তি যা কিছু তা বোঝায় না। আপনার প্রোগ্রামের আরও সমাবেশের অর্থ এই নয় যে প্রোগ্রামটি ধীর হবে, কারণ আপনি সমস্ত কোডের জন্য অ্যাকাউন্টিং করছেন না যা প্রিন্টফ ফাংশন তৈরি করে, যা প্রচুর কোড। আমার মতে, << অপারেটরটির সাথে প্রোট্টফের চেয়ে অনেক ভাল কৌতুকটি অপ্টিমাইজ করা সম্ভব, কারণ সংকলকটি ভেরিয়েবল এবং ফর্ম্যাটিংয়ের আরও ভাল ধারণা তৈরি করতে পারে।
Ignas2526

18
আমি এই উত্তর সম্পর্কে প্রচুর জিনিস পছন্দ করি তবে সম্ভবত আমার প্রিয় অংশটি হল "প্রত্যেকেই মনে করে যে তারা পারফরম্যান্সের বিষয়ে যত্নশীল, তবে কেউ এটি পরিমাপ করতে সাহস করে না।"
কাইল স্ট্র্যান্ড

203

থেকে সি ++ প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী :

[15.1] আমি কেন <iostream> গতানুগতিক পরিবর্তে ব্যবহার করব <cstdio>?

প্রকারের সুরক্ষা বাড়ান, ত্রুটিগুলি হ্রাস করুন, এক্সটেনসিবিলিটিটিকে মঞ্জুরি দিন এবং উত্তরাধিকার প্রদান করুন।

printf()তর্কযোগ্যভাবে ভাঙা নয়, এবং scanf()ত্রুটিযুক্ত প্রবণ হওয়া সত্ত্বেও সম্ভবত জীবিত, তবে উভয়ই সি ++ আই / ও কি করতে পারে সে সম্পর্কে সীমাবদ্ধ। সি ++ আই / ও (ব্যবহার <<এবং >>) সি এর সাথে সম্পর্কিত (ব্যবহার printf()এবং scanf()):

  • আরও প্রকারের সুরক্ষিত: <iostream>আই / ও'ড হ'ল ধরণের সংস্থার দ্বারা স্থিরভাবে জানা যায় known বিপরীতে, <cstdio>গতিশীলভাবে প্রকারগুলি বের করতে "%" ক্ষেত্রগুলি ব্যবহার করুন।
  • ত্রুটিযুক্ত প্রবণতা: এর সাথে <iostream>, রিডানডেন্ট "%" টোকেন নেই যা আসল বস্তুগুলি I / O'd এর সাথে সামঞ্জস্য রাখতে হবে। অপ্রয়োজনীয়তা অপসারণ করা এক শ্রেণীর ত্রুটিগুলি সরিয়ে দেয়।
  • এক্সটেনসিবল: সি ++ <iostream>মেকানিজম নতুন ব্যবহারকারী-সংজ্ঞায়িত প্রকারগুলিকে বিদ্যমান কোডটি ভঙ্গ না করে I / O'd করতে দেয়। বিশৃঙ্খলার কল্পনা করুন যদি প্রত্যেকে একই সাথে নতুনভাবে বেমানান "%" ক্ষেত্র যুক্ত করে printf()এবং scanf()?!
  • উত্তরাধিকারী: সি ++ <iostream>মেকানিজম যেমন std::ostreamএবং এর মতো বাস্তব ক্লাস থেকে তৈরি std::istream। ভিন্ন <cstdio>এর FILE*, এই বাস্তব ক্লাস এবং অত: পর উত্তরাধিকারসূত্রে হয়। এর অর্থ আপনার কাছে অন্যান্য ব্যবহারকারীর দ্বারা সংজ্ঞায়িত জিনিস থাকতে পারে যা দেখতে দেখতে এবং স্ট্রিমের মতো কাজ করে, তবুও এটি আপনার পছন্দমতো অদ্ভুত এবং দুর্দান্ত কিছু করতে পারে। আপনি নিজেরাই জানেন না এমন ব্যবহারকারীদের দ্বারা লিখিত আই / ও কোডের জিলিয়ন লাইনগুলি আপনি স্বয়ংক্রিয়ভাবে ব্যবহার করতে পারবেন এবং তাদের আপনার "বর্ধিত স্ট্রিম" শ্রেণি সম্পর্কে জানার দরকার নেই।

অন্যদিকে, printfপরিবর্তে এটি ব্যবহার ন্যায্যতা প্রতিপাদন করা হতে পারে উল্লেখযোগ্যভাবে দ্রুততর coutমধ্যে খুব নির্দিষ্ট এবং সীমিত ক্ষেত্রে। সর্বদা প্রথম প্রোফাইল। (উদাহরণস্বরূপ, http://programming-designs.com/2009/02/c-speed-test-part-2-printf-vs-cout /) দেখুন


2
অন্যদিকে, ফাস্টফর্ম্যাট লাইব্রেরি ( ফাস্টফর্ম্যাট.org ) রয়েছে যা একবারে টাইপ-সুরক্ষা, এক্সপ্রিভিটি এবং কার্য সম্পাদন করে। (এমন নয় যে আমি এটি এখনও চেষ্টা করেছি ...)
xtofl

3
@ মার্সেলো সম্ভবত কারণ এটি একটি ভাল সংক্ষিপ্তসার, সবকিছু উদ্ধৃত। ফর্ম্যাটিং ... হ্যাঁ, এটি বেশ খারাপ। আমার এটি স্থির করা উচিত ছিল, তবে এটি অন্যদের (নিজের মধ্যে অন্তর্ভুক্ত) এটি যত্ন নিয়েছে, যা অবশ্যই ঝকঝকে চেয়ে আরও গঠনমূলক।
মাইকেজ

2
ইদানীং হিসাবে printf()এছাড়াও প্রসার্য হতে অনুমিত হয়। Udrepper.livej Journal.com/20948.html
মেক্সিম এগারুশকিন

4
@ ম্যাক্সিম ইয়েগরোশকিন: স্ট্যান্ডার্ডের তেমন printfকোনও ক্ষমতা নেই। নন-পোর্টেবল লাইব্রেরি প্রক্রিয়াগুলি আইওস্ট্রিমের সম্পূর্ণ মানক এক্সটেনসিবিলিটির মতোই স্তরের স্তরে নয়।
বেন ভয়েগট

4
"অন্যদিকে, প্রিন্টএফ উল্লেখযোগ্যভাবে দ্রুত" প্রিন্টএফ আরও পরিষ্কার এবং ব্যবহার করা সহজ, এজন্যই যখন সম্ভব হয় আমি কৌতুক এড়িয়ে চলি।
ফ্লুরোসেন্টগ্রিন 5

43

লোকেরা প্রায়শই দাবি করে যে printfএটি অনেক দ্রুত। এটি মূলত একটি পৌরাণিক কাহিনী। আমি কেবল নিম্নলিখিত পরীক্ষার সাথে এটি পরীক্ষা করেছি:

cout with only endl                     1461.310252 ms
cout with only '\n'                      343.080217 ms
printf with only '\n'                     90.295948 ms
cout with string constant and endl      1892.975381 ms
cout with string constant and '\n'       416.123446 ms
printf with string constant and '\n'     472.073070 ms
cout with some stuff and endl           3496.489748 ms
cout with some stuff and '\n'           2638.272046 ms
printf with some stuff and '\n'         2520.318314 ms

উপসংহার: আপনি যদি কেবল নিউলাইনগুলি চান তবে ব্যবহার করুন printf; অন্যথায়, coutপ্রায় হিসাবে দ্রুত, বা আরও দ্রুত। আরও বিস্তারিত আমার ব্লগে পাওয়া যাবে ।

স্পষ্টতই, আমি বলার চেষ্টা করছি না যে iostreamসবসময় এর চেয়ে ভাল হয় printf; আমি কেবল এটি বলার চেষ্টা করছি যে কিছু সাধারণ, বিভ্রান্তিকর অনুমানের উপর ভিত্তি করে বন্য অনুমানের ভিত্তিতে আপনার বাস্তব তথ্যগুলির ভিত্তিতে একটি অবগত সিদ্ধান্ত নেওয়া উচিত।

আপডেট: আমি পরীক্ষার জন্য ব্যবহৃত পুরো কোডটি এখানে। g++কোনও অতিরিক্ত বিকল্প ছাড়াই সংকলিত (সময় বাদে -lrt)।

#include <stdio.h>
#include <iostream>
#include <ctime>

class TimedSection {
    char const *d_name;
    timespec d_start;
    public:
        TimedSection(char const *name) :
            d_name(name)
        {
            clock_gettime(CLOCK_REALTIME, &d_start);
        }
        ~TimedSection() {
            timespec end;
            clock_gettime(CLOCK_REALTIME, &end);
            double duration = 1e3 * (end.tv_sec - d_start.tv_sec) +
                              1e-6 * (end.tv_nsec - d_start.tv_nsec);
            std::cerr << d_name << '\t' << std::fixed << duration << " ms\n"; 
        }
};

int main() {
    const int iters = 10000000;
    char const *text = "01234567890123456789";
    {
        TimedSection s("cout with only endl");
        for (int i = 0; i < iters; ++i)
            std::cout << std::endl;
    }
    {
        TimedSection s("cout with only '\\n'");
        for (int i = 0; i < iters; ++i)
            std::cout << '\n';
    }
    {
        TimedSection s("printf with only '\\n'");
        for (int i = 0; i < iters; ++i)
            printf("\n");
    }
    {
        TimedSection s("cout with string constant and endl");
        for (int i = 0; i < iters; ++i)
            std::cout << "01234567890123456789" << std::endl;
    }
    {
        TimedSection s("cout with string constant and '\\n'");
        for (int i = 0; i < iters; ++i)
            std::cout << "01234567890123456789\n";
    }
    {
        TimedSection s("printf with string constant and '\\n'");
        for (int i = 0; i < iters; ++i)
            printf("01234567890123456789\n");
    }
    {
        TimedSection s("cout with some stuff and endl");
        for (int i = 0; i < iters; ++i)
            std::cout << text << "01234567890123456789" << i << std::endl;
    }
    {
        TimedSection s("cout with some stuff and '\\n'");
        for (int i = 0; i < iters; ++i)
            std::cout << text << "01234567890123456789" << i << '\n';
    }
    {
        TimedSection s("printf with some stuff and '\\n'");
        for (int i = 0; i < iters; ++i)
            printf("%s01234567890123456789%i\n", text, i);
    }
}

5
আপনার স্কোরগুলিতে প্রিন্টফ সহজেই চলাচল করেন (সংখ্যাগরিষ্ঠ ক্ষেত্রে)। আমি অবাক হয়েছি কেন আপনি যখন কাউট ব্যবহার করার পরামর্শ দিচ্ছেন যখন এটি পারফেক্ট হয়। যদিও আমি সম্মতি দিচ্ছি বাস্তবের ক্ষেত্রে পারফ খুব আলাদা নয় ..
মিসকাল 153

3
@ মিসাল153: আমি কেবল এটি বলার চেষ্টা করছি যে পারফরম্যান্সটি খুব আলাদা নয়, সুতরাং "কখনই কাউট ব্যবহার করবেন না কারণ এটি ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে कमিত হয়)। নোট করুন যে কাউটটির টাইপ-সুরক্ষার সুস্পষ্ট সুবিধা রয়েছে এবং প্রায়শই পাঠযোগ্যতাও রয়েছে। (আইওস্ট্রিমে ফ্লোটিং-পয়েন্ট ফর্ম্যাটিংটি ভয়াবহ ...)
টমাস

35
printf()এবং এর মধ্যে গুরুত্বপূর্ণ পার্থক্যটি std::ostreamহ'ল প্রাক্তন সকল যুক্তিগুলিকে একক কলে আউটপুট দেয় যেখানে std::ostreamপ্রত্যেকটির জন্য পৃথক কল অন্তর্ভুক্ত থাকে <<। পরীক্ষাটি কেবল একটি যুক্তি এবং একটি নতুন লাইনকে আউটপুট দেয়, এজন্য আপনি পার্থক্যটি দেখতে পাচ্ছেন না।
ম্যাক্সিম এগারুশকিন

12
সংকলককে এই কলগুলি ইনলাইন করতে সক্ষম হওয়া উচিত। এছাড়াও, printfবিভিন্ন ফর্ম্যাটিং স্পেসিফায়ারের জন্য সহায়ক ফাংশনগুলির জন্য কভারগুলির নীচে প্রচুর কল করা যেতে পারে ... এটি, বা এটি একটি বিমূর্ত একঘেয়ে কাজ। এবং আবার, ইনলাইনিংয়ের কারণে, এটির গতিতে মোটেও কোনও পার্থক্য করা উচিত নয়।
থমাস

4
আপনি আপনার টার্মিনালটির সময়সীমা নির্ধারণ করেছেন। ব্যবহারের sprintfবা fprintfএবং stringstreamবা fstream
বেন ভয়েগট

41

এবং আমি উদ্ধৃতি :

উচ্চ স্তরের পদগুলিতে, প্রধান পার্থক্যগুলি হ'ল সুরক্ষা (সিএসডিডিওতে এটি নেই), কার্য সম্পাদন (বেশিরভাগ আইস্ট্রিমগুলি বাস্তবায়নগুলি সিএসডিডিওর চেয়ে ধীর হয়) এবং এক্সটেনসিবিলিটি (আইওস্ট্রিমগুলি কাস্টম আউটপুট লক্ষ্যমাত্রা এবং ব্যবহারকারীর সংজ্ঞায়িত ধরণের বিরামবিহীন আউটপুটকে মঞ্জুরি দেয়)।


বিশেষত ইউনিক্সে যেখানে পসিক্সের সাথে আপনি কখনই জানেন না যে টাইপডেফগুলির মধ্যে কোনটি আসলেই কোন আকারের হয় তাই আপনার প্রচুর ক্যাসেটের প্রয়োজন হয় বা 99% প্রোগ্রাম হিসাবে আপনি এটি% d দিয়ে ঝুঁকিপূর্ণ করেন। % Z সি 99 নিয়ে আসার আগেও অনেক দিন সময় নিয়েছে। তবে সময়_t / অফ_t জন্য সঠিক ফর্ম্যাট নির্দেশের সন্ধান অবিরত রয়েছে।
লোথার

30

একটি হ'ল প্রিন্ট করে এমন একটি ফাংশন। অন্যটি একটি অবজেক্ট যা স্টাডআউটে বেশ কয়েকটি সদস্য ফাংশন এবং operator<<প্রিন্টের ওভারলোড সরবরাহ করে । আরও অনেক পার্থক্য রয়েছে যা আমি গণনা করতে পারি তবে আপনি কী পরে তা নিশ্চিত নই।


12

আমার জন্য, আসল পার্থক্যগুলি যা আমাকে 'প্রিন্টফ' এর পরিবর্তে 'কাউট'-এ যেতে দেয়:

1) << অপারেটর আমার ক্লাসের জন্য ওভারলোড করা যাবে।

2) আউটপুট স্ট্রিম সহজেই কোনও ফাইলে পরিবর্তিত হতে পারে: (: কপি পেস্ট :)

#include <iostream>
#include <fstream>
using namespace std;

int main ()
{
    cout << "This is sent to prompt" << endl;
    ofstream file;
    file.open ("test.txt");
    streambuf* sbuf = cout.rdbuf();
    cout.rdbuf(file.rdbuf());
    cout << "This is sent to file" << endl;
    cout.rdbuf(sbuf);
    cout << "This is also sent to prompt" << endl;
    return 0;
}

3) আমি কাউটকে আরও পাঠযোগ্য বলে মনে করি, বিশেষত যখন আমাদের অনেকগুলি পরামিতি থাকে।

ফর্ম্যাট করার বিকল্পগুলির সাথে একটি সমস্যাcout options ডেটা ফর্ম্যাট করা (যথার্থতা, ন্যায়সঙ্গত ইত্যাদি) printfআরও সহজ।


1
এটা সুন্দর. আমি কীভাবে জানতে পারি যে কোনও বিদেশী লাইব্রেরি থ্রেডে কেউ এইভাবে গ্লোবাল কাউটকে পরিবর্তন করতে পারে না?
vp_arth

1
আপনি সহজেই printfকোনও ফাইলের পরিবর্তে এটির বদলে পরিবর্তন করতে পারেন fprintf...
কফি টেবিলস্প্রেসো

5

দুটি বিষয় যা অন্যথায় এখানে উল্লেখ করা হয়নি তা আমি উল্লেখযোগ্য বলে মনে করি:

1) coutআপনি যদি ইতিমধ্যে এসটিএল ব্যবহার না করেন তবে প্রচুর লাগেজ বহন করে। এটি আপনার অবজেক্ট ফাইলে দ্বিগুণ কোড যুক্ত করে printf। এটিও সত্য string, এবং এটি আমার নিজের স্ট্রিং গ্রন্থাগারটি ব্যবহার করার প্রবণতার কারণ।

2) coutঅতিরিক্ত লোড <<অপারেটরগুলি ব্যবহার করে , যা আমি দুর্ভাগ্যজনক বলে মনে করি। আপনি যদি <<অপারেটরটিকে তার উদ্দেশ্যযুক্ত উদ্দেশ্যে (শিফট বাম দিকে) ব্যবহার করেন তবে এটি বিভ্রান্তি যুক্ত করতে পারে । অপারেটরগুলি তাদের উদ্দেশ্যযুক্ত ব্যবহারের জন্য স্পর্শকাতর উদ্দেশ্যে ব্যক্তিগতভাবে আমি ওভারলোড পছন্দ করি না।

নীচের লাইন: আমি যদি ইতিমধ্যে এসটিএল ব্যবহার করি তবে আমি cout(এবং string) ব্যবহার করব । অন্যথায়, আমি এটি এড়ানোর ঝোঁক।


4

আদিমগুলি সহ, আপনি সম্ভবত কোনটি ব্যবহার করেন তা সম্পূর্ণ বিবেচনা করে না। আমি বলি যে আপনি যখন জটিল অবজেক্টগুলি আউটপুট করতে চান তখন এটির দরকারীতা কোথায় পাওয়া যায়।

উদাহরণস্বরূপ, যদি আপনার কোনও ক্লাস থাকে,

#include <iostream>
#include <cstdlib>

using namespace std;

class Something
{
public:
        Something(int x, int y, int z) : a(x), b(y), c(z) { }
        int a;
        int b;
        int c;

        friend ostream& operator<<(ostream&, const Something&);
};

ostream& operator<<(ostream& o, const Something& s)
{
        o << s.a << ", " << s.b << ", " << s.c;
        return o;
}

int main(void)
{
        Something s(3, 2, 1);

        // output with printf
        printf("%i, %i, %i\n", s.a, s.b, s.c);

        // output with cout
        cout << s << endl;

        return 0;
}

এখন উপরেরটি এগুলি দুর্দান্ত মনে হচ্ছে না, তবে ধরা যাক আপনার কোডে একাধিক জায়গায় এটি আউটপুট করতে হবে। শুধু তাই নয়, আসুন আপনাকে একটি ক্ষেত্র যুক্ত করুন "int d"। কাউট সহ, আপনাকে কেবল একবারে এটি পরিবর্তন করতে হবে। তবে প্রিন্টফের সাহায্যে আপনাকে এটিকে সম্ভবত অনেক জায়গায় পরিবর্তন করতে হবে এবং কেবল এটিই নয়, আপনাকে কোনটি আউটপুট দিতে হবে তা নিজেকে স্মরণ করিয়ে দিতে হবে।

কৌতুকের সাহায্যে, আপনার কোডটি রক্ষণাবেক্ষণের জন্য ব্যয় করা অনেক সময় হ্রাস করতে পারবেন এবং এটিই নয় যে আপনি যদি নতুন অ্যাপ্লিকেশনটিতে "সামथিং" অবজেক্টটি পুনরায় ব্যবহার করেন, আপনাকে আউটপুট সম্পর্কে সত্যই চিন্তা করতে হবে না।


এছাড়াও, পারফরম্যান্সের জিনিসটি যুক্ত করার জন্য, আমি বলব যে যদি আপনার অ্যাপ্লিকেশনটি পারফরম্যান্সের জন্য তৈরি করা হয় তবে আপনার কিছুই আউটপুট করা উচিত নয়। স্ট্যান্ডের কোনও ধরণের আউটপুট বরং ব্যয়বহুল এবং ধীর। আমি বলছি আপনার এড়ানো উচিত এবং কেবল যখন আউটপুট করা উচিত যখন এটি করা একেবারে প্রয়োজন।
ড্যানিয়েল

মনে রাখবেন যে আপনার শ্রেণিতে ব্যক্তিগত সদস্য থাকতে পারে আপনি এত সহজে বাইরে থেকে অ্যাক্সেস করতে পারবেন না। আউটপুট অপারেটরের সাথে আপনার ঠিক এক অবস্থান রয়েছে যা আপনার শ্রেণীর সাথে বন্ধুত্বপূর্ণ হওয়া দরকার এবং এখন আপনি এটিকে যে কোনও জায়গায় আউটপুট করতে পারেন এমনকি এমন কোডেও যা আপনি জানতেন না।
hochl

2

অবশ্যই আপনি রক্ষণাবেক্ষণের জন্য কিছুটা "ভাল" লিখতে পারেন:

#include <iostream>
#include <cstdlib>

using namespace std;

class Something
{
    public:
        Something(int x, int y, int z) : a(x), b(y), c(z) { }
        int a;
        int b;
        int c;

        friend ostream& operator<<(ostream&, const Something&);

        void print() const { printf("%i, %i, %i\n", a, b, c); }
};

ostream& operator<<(ostream& o, const Something& s)
{
    o << s.a << ", " << s.b << ", " << s.c;
    return o;
}

int main(void)
{
    Something s(3, 2, 1);

    // Output with printf
    s.print(); // Simple as well, isn't it?

    // Output with cout
    cout << s << endl;

    return 0;
}

এবং কাউট বনাম প্রিন্টফের কিছুটা বর্ধিত পরীক্ষা, 'ডাবল' এর পরীক্ষা যুক্ত করেছে, যদি কেউ আরও পরীক্ষা করতে চায় (ভিজ্যুয়াল স্টুডিও ২০০৮, এক্সিকিউটেবলের প্রকাশ সংস্করণ):

#include <stdio.h>
#include <iostream>
#include <ctime>

class TimedSection {
    char const *d_name;
    //timespec d_start;
    clock_t d_start;

    public:
        TimedSection(char const *name) :
            d_name(name)
        {
            //clock_gettime(CLOCK_REALTIME, &d_start);
            d_start = clock();
        }
        ~TimedSection() {
            clock_t end;
            //clock_gettime(CLOCK_REALTIME, &end);
            end = clock();
            double duration = /*1e3 * (end.tv_sec - d_start.tv_sec) +
                              1e-6 * (end.tv_nsec - d_start.tv_nsec);
                              */
                              (double) (end - d_start) / CLOCKS_PER_SEC;

            std::cerr << d_name << '\t' << std::fixed << duration * 1000.0 << " ms\n";
        }
};


int main() {
    const int iters = 1000000;
    char const *text = "01234567890123456789";
    {
        TimedSection s("cout with only endl");
        for (int i = 0; i < iters; ++i)
            std::cout << std::endl;
    }
    {
        TimedSection s("cout with only '\\n'");
        for (int i = 0; i < iters; ++i)
            std::cout << '\n';
    }
    {
        TimedSection s("printf with only '\\n'");
        for (int i = 0; i < iters; ++i)
            printf("\n");
    }
    {
        TimedSection s("cout with string constant and endl");
        for (int i = 0; i < iters; ++i)
            std::cout << "01234567890123456789" << std::endl;
    }
    {
        TimedSection s("cout with string constant and '\\n'");
        for (int i = 0; i < iters; ++i)
            std::cout << "01234567890123456789\n";
    }
    {
        TimedSection s("printf with string constant and '\\n'");
        for (int i = 0; i < iters; ++i)
            printf("01234567890123456789\n");
    }
    {
        TimedSection s("cout with some stuff and endl");
        for (int i = 0; i < iters; ++i)
            std::cout << text << "01234567890123456789" << i << std::endl;
    }
    {
        TimedSection s("cout with some stuff and '\\n'");
        for (int i = 0; i < iters; ++i)
            std::cout << text << "01234567890123456789" << i << '\n';
    }
    {
        TimedSection s("printf with some stuff and '\\n'");
        for (int i = 0; i < iters; ++i)
            printf("%s01234567890123456789%i\n", text, i);
    }
    {
        TimedSection s("cout with formatted double (width & precision once)");
        std::cout << std::fixed << std::scientific << std::right << std::showpoint;
        std::cout.width(8);
        for (int i = 0; i < iters; ++i)
            std::cout << text << 8.315 << i << '\n';
    }
    {
        TimedSection s("cout with formatted double (width & precision on each call)");
        std::cout << std::fixed << std::scientific << std::right << std::showpoint;

        for (int i = 0; i < iters; ++i)
            { std::cout.width(8);
              std::cout.precision(3);
              std::cout << text << 8.315 << i << '\n';
            }
    }
    {
        TimedSection s("printf with formatted double");
        for (int i = 0; i < iters; ++i)
            printf("%8.3f%i\n", 8.315, i);
    }
}

ফলাফল হলো:

cout with only endl    6453.000000 ms
cout with only '\n'    125.000000 ms
printf with only '\n'    156.000000 ms
cout with string constant and endl    6937.000000 ms
cout with string constant and '\n'    1391.000000 ms
printf with string constant and '\n'    3391.000000 ms
cout with some stuff and endl    9672.000000 ms
cout with some stuff and '\n'    7296.000000 ms
printf with some stuff and '\n'    12235.000000 ms
cout with formatted double (width & precision once)    7906.000000 ms
cout with formatted double (width & precision on each call)    9141.000000 ms
printf with formatted double    3312.000000 ms

বাহ, এর endlচেয়ে এত কম দক্ষ কেন '\n'?
নিকোলাস হ্যামিল্টন

1
আমি বিশ্বাস করি এটি কারণ endlএটি বাফারকে ফ্লাশ করে এবং \nতা করে না, যদিও আমি নিশ্চিত নই যে এটির কারণটি অবশ্যই এটি।
কালেব জু

এটি প্রশ্নের উত্তোলনকারী নয়, এটি ড্যানিয়েল এবং থমাসের উত্তরের মতো ।
ফ্যাবিও বলেছেন মনিকা পুনরায়

2

আমি উল্লেখ করতে চাই যে আপনি যদি সি ++ তে থ্রেড নিয়ে খেলতে চান তবে আপনি যদি coutকিছু আকর্ষণীয় ফলাফল পেতে পারেন।

এই কোডটি বিবেচনা করুন:

#include <string>
#include <iostream>
#include <thread>

using namespace std;

void task(int taskNum, string msg) {
    for (int i = 0; i < 5; ++i) {
        cout << "#" << taskNum << ": " << msg << endl;
    }
}

int main() {
    thread t1(task, 1, "AAA");
    thread t2(task, 2, "BBB");
    t1.join();
    t2.join();
    return 0;
}

// g++ ./thread.cpp -o thread.out -ansi -pedantic -pthread -std=c++0x

এখন, আউটপুট সব পরিবর্তন হয়ে আসে। এটি বিভিন্ন ফলাফলও পেতে পারে, বেশ কয়েকবার কার্যকর করার চেষ্টা করুন:

##12::  ABABAB

##12::  ABABAB

##12::  ABABAB

##12::  ABABAB

##12::  ABABAB

আপনি printfএটি সঠিক পেতে ব্যবহার করতে পারেন , বা আপনি ব্যবহার করতে পারেন mutex

#1: AAA
#2: BBB
#1: AAA
#2: BBB
#1: AAA
#2: BBB
#1: AAA
#2: BBB
#1: AAA
#2: BBB

আনন্দ কর!


2
ডাব্লুটিএফ threadএস আউটপুট গো বাদাম তৈরি করবেন না। আমি কেবল পুনরুত্পাদন করেছি এবং উভয় xyzএবং ABCআউটপুট খুঁজে পেয়েছি । সেখানে mangling হয়নি B / W ABCযেমন ABABAB
অভিনব গৌনিয়াল

1
coutথ্রেডগুলির সাথে কীভাবে কাজ করে তা আমি জানি না তবে আমি নিশ্চিতভাবে জানি যে আপনি যে কোডটি দেখিয়ে দিচ্ছেন তা সেই ফলাফলগুলি নয় যা আপনি এই ফলাফলগুলি পেয়েছিলেন। আপনার কোডটি "ABC"থ্রেড 1 এবং "xyz"থ্রেড 2 এর জন্য স্ট্রিংটি কেটে দেয় তবে আপনার আউটপুটটি প্রদর্শন করে AAAএবং BBB। দয়া করে এটি ঠিক করুন, কারণ এখনই এটি বিভ্রান্তিকর।
ফ্যাবিও বলেছেন মনিকা পুনরায়

1
cout<< "Hello";
printf("%s", "Hello"); 

উভয়ই মান মুদ্রণের জন্য ব্যবহৃত হয়। তাদের সম্পূর্ণ ভিন্ন বাক্য গঠন রয়েছে। সি ++ উভয়ই রয়েছে, সিটিতে কেবল প্রিন্টফ রয়েছে।


19
... কি? আপনি কিছু মিশ্রিত করেছেন?
xtofl

1
ইস্যু স্থির। -1 কারণ এটির ফিক্সিংয়ের প্রয়োজন ছিল এবং উত্তরটি পছন্দ হতে অনেক কিছু ফেলে।
ইয়াকোবি 20'10

3
ফাংশনটির নামগুলি বিপরীত করা হয়েছিল: প্রোট্ট সিন্ট্যাক্সের সাথে কাউট ব্যবহৃত হত, এবং প্রাউডফটি কোউটের সিনট্যাক্সের সাথে ব্যবহৃত হত। এমনকি গ্রহণ করা উচিত ছিল না!
মাহমুদ আল-কুদসি

2
এবং কাউটের প্রধান অসুবিধা হ'ল এটি অপারেটর ব্যবহার করে << যা ভার্জোজ এবং কুরুচিপূর্ণ এবং তর্কযুক্ত অপারেটরের অপব্যবহার। :)
জলফ

8
যদিও এটি নিশ্চিতভাবে সেরা উত্তর নয়, তবে আমি বুঝতে পারি না যে স্ক্যামম্যানকে তার উত্তরের জন্য কীভাবে শাস্তি দেওয়া হচ্ছে কারণ এটি সেরা উত্তর হিসাবে বেছে নেওয়া হয়েছিল। এক্সবিটের আইএমওর আরও খারাপ উত্তর রয়েছে তবে এতে -1 ভোট রয়েছে। আমি বলছি না যে এক্সবিটকে আরও বেশি ভোট দেওয়া উচিত, তবে আমি ওপি-র ভুলের চেয়ে ভোট স্ক্যাচম্যানকে ন্যায্য বলে মনে করি না ...
জেসি

1

আমি বলতে চাই যে এক্সটেনসিবিলিটির অভাব printfপুরোপুরি সত্য নয়:
সি তে, এটি সত্য। তবে সি তে, কোন বাস্তব ক্লাস নেই।
সি ++ এ, কাস্ট অপারেটরটিকে ওভারলোড করা সম্ভব, সুতরাং কোনও char*অপারেটরকে ওভারলোড করা এবং এটি ব্যবহার করে printf:

Foo bar;
...;
printf("%s",bar);

সম্ভব হতে পারে, যদি Foo ভাল অপারেটরটি ওভারলোড করে। অথবা আপনি যদি একটি ভাল পদ্ধতি তৈরি করেন। সংক্ষেপে, আমার জন্য printfযেমন এক্সটেনসিবল cout

প্রযুক্তিগত যুক্তি আমি সি ++ টি স্ট্রিমের জন্য দেখতে পাচ্ছি (সাধারণভাবে ... কেবলমাত্র কোট নয়)) হ'ল:

  • Typesafety। (এবং, যাইহোক, আমি যদি একক মুদ্রণ করতে চাই তবে আমি '\n'ব্যবহার করব putchar('\n')... পোকা মারার জন্য আমি নিউক-বোম্ব ব্যবহার করব না))

  • সহজ শিখতে। (শেখার জন্য কোনও "জটিল" পরামিতি নেই, কেবল ব্যবহারের জন্য <<এবং >>অপারেটরগুলি)

  • স্থানীয়ভাবে কাজ করুন std::string(কারণ printfরয়েছে std::string::c_str()তবে scanf?)

জন্য printfআমি দেখুন:

  • সহজ, বা কমপক্ষে খাটো (অক্ষরের পরিভাষায় লিখিত) জটিল ফর্ম্যাটিং। অনেক বেশি পঠনযোগ্য, আমার জন্য (স্বাদের বিষয়টি আমি অনুমান করি)।

  • ফাংশনটি কী করেছে তার আরও ভাল নিয়ন্ত্রণ (কতগুলি অক্ষর যেখানে লিখিত আছে এবং %nফর্ম্যাটারটি রয়েছে তা ফিরিয়ে দিন : "কিছুই মুদ্রিত নয় The আর্গুমেন্টটি অবশ্যই স্বাক্ষরিত ইন্টির দিকে নির্দেশক হওয়া উচিত, যেখানে এখন পর্যন্ত লেখা অক্ষরের সংখ্যা সংরক্ষণ করা হয়েছে।" ( প্রিন্টফ থেকে - সি ++ রেফারেন্স )

  • ভাল ডিবাগিং সম্ভাবনা। শেষ যুক্তি হিসাবে একই কারণে।

আমার ব্যক্তিগত পছন্দগুলি printf(এবং scanf) ফাংশনে যায়, মূলত আমি সংক্ষিপ্ত রেখাগুলি পছন্দ করি এবং প্রিন্টিং পাঠ্যের ক্ষেত্রে টাইপ সমস্যাগুলি এড়ানো সত্যিই কঠিন বলে আমি মনে করি না। সি-স্টাইলের ক্রিয়াকলাপগুলির সাথে কেবলমাত্র আমি আপত্তি জানাই std::stringএটি সমর্থিত নয়। আমরা একটি মধ্য দিয়ে যেতে char*এটিকে দেবার আগে printf(সঙ্গে std::string::c_str()আমরা পড়েছি করতে চান তাহলে, কিন্তু কিভাবে লিখব?)


3
সংকলকটির ভারেগস ফাংশনগুলির জন্য কোনও ধরণের তথ্য নেই, সুতরাং এটি প্রকৃত প্যারামিটারকে রূপান্তর করবে না ( মানক ইন্টিগ্রাল প্রচারগুলির মতো ডিফল্ট আর্গুমেন্ট প্রচারগুলি ব্যতীত )। 5.2.2p7 দেখুন। কোনও ব্যবহারকারী-সংজ্ঞায়িত রূপান্তর char*ব্যবহৃত হবে না।
বেন ভয়েগট

এমনকি যদি এটি কাজ করে তবে এটি স্প্রিন্টফ এক্সটেনসিবিলিটির উদাহরণ হতে পারে না, স্প্রিন্টফ কী প্রত্যাশা করে তা দেওয়ার জন্য কেবল একটি চতুর হ্যাক, এবং এটি কিছু গুরুতর বিষয়গুলিকে উপেক্ষা করে যেমন char*জীবন এবং কত দিন, এবং ব্যবহারকারী-সংজ্ঞায়িত বিপদগুলি অন্তর্নিহিত কাস্ট।
মার্সেলো ক্যান্টোস

1

আরও পার্থক্য: "প্রিন্টফ" একটি পূর্ণসংখ্যা মান প্রদান করে (মুদ্রিত অক্ষরের সংখ্যার সমান) এবং "কাউট" কোনও কিছুই ফেরায় না

এবং.

cout << "y = " << 7; পারমাণবিক নয়।

printf("%s = %d", "y", 7); পারমাণবিক।

cout typechecking সম্পাদন করে, প্রিন্টফ করে না।

এর সাথে আইওস্ট্রিমের সমতুল্য নেই "% d"


3
coutকোনও জিনিস ফেরত দেয় না কারণ এটি একটি বস্তু, কোনও ফাংশন নয়। operator<<কিছু ফেরত দেয় (সাধারণত এর বাম অপারেণ্ড, তবে একটি ত্রুটি থাকলে একটি মিথ্যা মান)। এবং printfকলটি কোন অর্থে "পারমাণবিক"?
কিথ থম্পসন

9
এটি পারমাণবিক বোমার মতো। printf("%s\n",7);
নির্বোধ শব্দ

@artlessnoise অপেক্ষা করুন কেন বিভাজন দোষ? %sহয়?
অভিনব গৌনিয়াল

1
এটিই 'পারমাণবিক বোমা' বিবৃতিটির মূল বিষয়। একটি printf % s আর্গুমেন্টে একটি নাল টার্মিনেটেড স্ট্রিংয়ের একটি বৈধ পয়েন্টার থাকতে হবে। মেমরি পরিসীমা '7' (একটি পয়েন্টার) সাধারণত বৈধ হয় না; একটি বিভাজন ত্রুটি ভাগ্যবান হতে পারে। কিছু সিস্টেমে, '7' একটি কনসোলে প্রচুর আবর্জনা মুদ্রণ করতে পারে এবং প্রোগ্রামটি বন্ধ হওয়ার আগে আপনাকে এটির জন্য একদিন দেখতে হবে। অন্য কথায়, এটি সম্পর্কে একটি খারাপ জিনিস printf। স্থিতিশীল বিশ্লেষণ সরঞ্জামগুলি এই সমস্যার অনেকগুলিই ধরতে পারে।
নির্মম আওয়াজ

প্রযুক্তিগতভাবে printfটাইপচেকিং না করা অবস্থায়, আমি কখনও কখনও এমন সংকলক ব্যবহার করি নি যা আমাকে টাইপ ত্রুটি সম্পর্কে সতর্ক করে না printf...
কফি টেবিলস্প্রেসো

1

টিএল; ডিআর: উত্পাদিত মেশিন কোডের আকার , পারফরম্যান্স , পাঠযোগ্যতা এবং কোডিং সময় সম্পর্কিত এটিকে সহ অনলাইনে এলোমেলো মন্তব্যে বিশ্বাস করার আগে সর্বদা আপনার নিজের গবেষণা করুন।

আমি কোন বিশেষজ্ঞ নই। পারফরম্যান্স সমস্যার কারণে এম্বেড থাকা সিস্টেমে কীভাবে আমাদের সি ++ ব্যবহার করা এড়ানো উচিত সে সম্পর্কে কথা বলার জন্য আমি কেবলমাত্র দুই সহকর্মীকে শুনতে পেয়েছি। ভাল, যথেষ্ট আকর্ষণীয়, আমি একটি বাস্তব প্রকল্পের কাজের উপর ভিত্তি করে একটি মানদণ্ড করেছি।

এই কাজের মধ্যে, আমাদের র‌্যামে কিছু কনফিগারেশন লিখতে হয়েছিল। কিছুটা এইরকম:

কফি = গরম
চিনি =
দুধ নয় = স্তন
ম্যাক = এএ: বিবি: সিসি: ডিডি: ইই: এফএফ

এখানে আমার বেঞ্চমার্ক প্রোগ্রামগুলি (হ্যাঁ, আমি জানি ওপি প্রিন্টফ () সম্পর্কে জিজ্ঞাসা করেছিল, এফপ্রিন্টফ () নয়। সারমর্মটি ক্যাপচার করার চেষ্টা করুন এবং যাইহোক, ওপির লিঙ্কটি যেভাবেই হোক এফপ্রিন্টএফ () এ নির্দেশ করে।)

সি প্রোগ্রাম:

char coffee[10], sugar[10], milk[10];
unsigned char mac[6];

/* Initialize those things here. */

FILE * f = fopen("a.txt", "wt");

fprintf(f, "coffee=%s\nsugar=%s\nmilk=%s\nmac=%02X:%02X:%02X:%02X:%02X:%02X\n", coffee, sugar, milk, mac[0], mac[1],mac[2],mac[3],mac[4],mac[5]);

fclose(f);

সি ++ প্রোগ্রাম:

//Everything else is identical except:

std::ofstream f("a.txt", std::ios::out);

f << "coffee=" << coffee << "\n";
f << "sugar=" << sugar << "\n";
f << "milk=" << milk << "\n";
f << "mac=" << (int)mac[0] << ":"
    << (int)mac[1] << ":"
    << (int)mac[2] << ":"
    << (int)mac[3] << ":"
    << (int)mac[4] << ":"
    << (int)mac[5] << endl;
f.close();

আমি তাদের উভয়কে 100,000 বার লুপ করার আগে পলিশ করার জন্য যথাসাধ্য চেষ্টা করেছি। ফলাফল এখানে:

সি প্রোগ্রাম:

real    0m 8.01s
user    0m 2.37s
sys     0m 5.58s

সি ++ প্রোগ্রাম:

real    0m 6.07s
user    0m 3.18s
sys     0m 2.84s

অবজেক্ট ফাইলের আকার:

C   - 2,092 bytes
C++ - 3,272 bytes

উপসংহার: আমার খুব নির্দিষ্ট প্ল্যাটফর্মে , একটি খুব নির্দিষ্ট প্রসেসর সহ , লিনাক্স কার্নেলের একটি খুব নির্দিষ্ট সংস্করণ চালু করে, একটি প্রোগ্রাম চালানোর জন্য, যা একটি সুনির্দিষ্ট কার্য সম্পাদন করার জন্য, জিসিসির একটি নির্দিষ্ট সংস্করণ সহ সংকলিত একটি প্রোগ্রাম চালাতে , আমি বলব সি ++ পদ্ধতিটি আরও উপযুক্ত কারণ এটি উল্লেখযোগ্যভাবে দ্রুত চালিত হয় এবং আরও ভাল পাঠযোগ্যতা সরবরাহ করে। অন্যদিকে, সি ছোট পায়ের ছাপ দেয়, আমার মতে, এর অর্থ প্রায় কিছুই নয় কারণ প্রোগ্রামের আকারটি আমাদের উদ্বেগের নয়।

রিমবার, ওয়াইএমএমভি।


আমি অসম্মতি জানাই যে সি ++ এই উদাহরণে আরও পঠনযোগ্য, কারণ আপনার উদাহরণটি একক প্রিন্টফ কলটিতে একাধিক লাইন প্যাক করে। আপনি সি ++ কোডটি করেছেন সে তুলনায় এটি স্বাভাবিকভাবেই কম পঠনযোগ্য এবং সি তে খুব কমই করা হয় কারণ এটি পড়া শক্ত এবং বজায় রাখা শক্ত। ন্যায্য তুলনা সি থেকে আলাদা প্রিন্টফে ছড়িয়ে দেবে, এটি পৌঁছানোর লাইনের জন্য একটি।
maharvey67

1
@ maharvey67 আপনি যা বলেছেন তা সত্য। তবে আমি সিটিতে যে উদাহরণটি দিয়েছি তা পারফরম্যান্সের বিবেচনায় ছিল। ইতিমধ্যে ইতিমধ্যে সি ++ সমতুল্যের চেয়ে এফপ্রিন্টফের কাছে প্যাক-ইন-ওয়ান কলটি দুই সেকেন্ড ধীর ছিল। আমি যদি সি কোডটি পঠনযোগ্য করে তুলতাম তবে এটি আরও ধীর হতে পারে। দাবি অস্বীকার: এটি এক বছর আগে এবং আমি মনে করি আমি সি এবং সি ++ কোড উভয়ই পোলিশ করার জন্য যথাসাধ্য চেষ্টা করেছি। আমার কোনও প্রমাণ নেই যে এফপ্রিন্টফের কাছে পৃথক কলগুলি একটি একক কলের চেয়ে দ্রুততর হবে তবে আমি যেভাবে এটি করেছি তা সম্ভবত এটি ইঙ্গিত দেয়।
ওয়েসলি

0

আমি প্রোগ্রামার নই, তবে আমি একজন মানবিক প্রকৌশলী হয়েছি। আমি মনে করি একটি প্রোগ্রামিং ভাষা শেখা, বুঝতে এবং ব্যবহার করা সহজ হওয়া উচিত এবং এর প্রয়োজন এটির একটি সহজ এবং ধারাবাহিক ভাষাগত কাঠামো। যদিও সমস্ত ভাষা প্রতীকী এবং এইভাবে, এর মূল ভিত্তিতে, স্বেচ্ছাসেবী, সেখানে সম্মেলন হয় এবং সেগুলি অনুসরণ করে ভাষা শিখতে এবং ব্যবহার সহজ করে তোলে।

সি ++ এবং ফাংশন (পরামিতি) হিসাবে লিখিত অন্যান্য ভাষায় প্রচুর ফাংশন রয়েছে, এটি একটি সিনট্যাক্স যা প্রাক কম্পিউটারের যুগে গণিতের কার্যকরী সম্পর্কের জন্য মূলত ব্যবহৃত হয়েছিল। printf()এই বাক্য গঠনটি অনুসরণ করে এবং সি ++ র লেখকরা যদি ফাইল পড়তে এবং লেখার জন্য কোনও যুক্তিযুক্তভাবে আলাদা পদ্ধতি তৈরি করতে চান তবে তারা কেবল একই জাতীয় বাক্য গঠন ব্যবহার করে একটি ভিন্ন ফাংশন তৈরি করতে পারতেন।

পাইথনে আমরা অবশ্যই মোটামুটি মানক object.methodসিনট্যাক্স ব্যবহার করে মুদ্রণ করতে পারি , যেমন ভেরিয়েবল নাম.প্রিন্ট, যেহেতু ভেরিয়েবলগুলি বস্তু, তবে সি ++ এ সেগুলি হয় না।

আমি কাউট সিনট্যাক্সের পছন্দ নই কারণ << অপারেটর কোনও নিয়ম অনুসরণ করে না। এটি একটি পদ্ধতি বা ফাংশন, অর্থাৎ এটি একটি প্যারামিটার নেয় এবং এটিতে কিছু করে। তবে এটি লিখিত যেমন এটি একটি গাণিতিক তুলনা অপারেটর ছিল। এটি মানুষের কারণগুলির দিক থেকে একটি দুর্বল পদ্ধতি approach


-1

printfএকটি ফাংশন যেখানে coutএকটি পরিবর্তনশীল হয়।


6
আমি রোল-ব্যাক করেছি কারণ, যদিও উত্তরটি নিজেই ভুল হতে পারে তবে এটি এখনও একটি আসল উত্তর। আপনি যদি (সঠিকভাবে) উত্তরটি ভুল বলে মনে করেন, আপনার দুটি বিকল্প রয়েছে: 1) একটি মন্তব্য যুক্ত করুন বা 2) একটি নতুন উত্তর যুক্ত করুন (বা উভয় করুন)। কারওর উত্তরকে এমন পরিবর্তন করবেন না যে এটি লেখকের উদ্দেশ্য থেকে সম্পূর্ণ ভিন্ন কিছু বলে।
চিহ্নিত করুন

1
printfএকটি ফাংশন, তবে printf()এটি একটি ফাংশন কল =)
ভিপি_আর্থ

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