সি-তে প্রিন্টফ () এবং পুটস () এর মধ্যে পার্থক্য কী?


176

আমি জানি আপনার সাথে মুদ্রণ করতে পারেন printf()এবং puts()। আমি এটি দেখতে পাচ্ছি যা printf()আপনাকে ভেরিয়েবলগুলিকে ইন্টারপোলেট করতে এবং ফর্ম্যাটিং করতে দেয়।

এটি puts()কেবল একটি আদি সংস্করণ printf()printf()স্ট্রিং ইন্টারপোলেশন ছাড়াই এটি কি প্রতিটি সম্ভাব্যের জন্য ব্যবহার করা উচিত ?



47
রাখার পরিবর্তে প্রিন্টফ ব্যবহার করার ক্ষেত্রে কেবল একটি নোট: printf(variable)স্ট্রিং মুদ্রণের জন্য কখনও কখনও করবেন না । ব্যবহার করুন puts(variable)বা printf("%s', variable)। ভেরিয়েবল ফরম্যাট স্ট্রিংটি ব্যবহার করার ক্ষেত্রে একটি সুরক্ষা ঝুঁকি রয়েছে: যদি কোনও আক্রমণকারী দ্বারা পরিবর্তনশীলটি লেখা যায় তবে তারা বিন্যাসের স্ট্রিংগুলি ব্যবহার করে প্রোগ্রামটিতে আক্রমণ করতে পারে।
জ্যান লিংস

উত্তর:


141

putsএর চেয়ে সহজ printfতবে সচেতন থাকবেন যে প্রাক্তনটি স্বয়ংক্রিয়ভাবে একটি নতুন লাইন যুক্ত করে। যে না কি আপনি চান, আপনি যা করতে পারেন fputsstdout- এ বা ব্যবহার করার জন্য আপনার স্ট্রিং printf


8
আমি মনে করি আউটপুটযুক্ত স্ট্রিংয়ে অতিরিক্ত ভেরিয়েবল যুক্ত করার জন্য অতিরিক্ত যুক্তিগুলি প্রিন্টফের উল্লেখ করাও গুরুত্বপূর্ণ।
এরুতান 409

99

(এটি জ্যান লিনেক্সের একটি মন্তব্যে উল্লেখ করা হয়েছে, তবে আমি মনে করি এটি গ্রহণযোগ্য বলে দাবি করেছে - গ্রহণযোগ্য উত্তরটি উল্লেখ না করে)।

puts(mystr);এবং এর মধ্যে অপরিহার্য পার্থক্য printf(mystr);হ'ল পরবর্তীকালে আর্গুমেন্টকে বিন্যাসের স্ট্রিং হিসাবে ব্যাখ্যা করা হয় । স্ট্রিংটিতে কোনও নিয়ন্ত্রণ অক্ষর ( %) যুক্ত না থাকলে ফলাফল প্রায়শই একই (যুক্ত নিউলাইন ব্যতীত) হতে পারে তবে আপনি যদি এটির উপর নির্ভর করতে না পারেন (যদি mystrআক্ষরিক পরিবর্তে পরিবর্তনশীল হয়) আপনার এটি ব্যবহার করা উচিত নয়

সুতরাং, এটি সাধারণত বিপজ্জনক-এবং ধারণাগতভাবে ভুল - এর একক যুক্তি হিসাবে গতিশীল স্ট্রিং পাস করা printf:

  char * myMessage;
  // ... myMessage gets assigned at runtime, unpredictable content
  printf(myMessage);  // <--- WRONG! (what if myMessage contains a '%' char?) 
  puts(myMessage);    // ok
  printf("%s\n",myMessage); // ok, equivalent to the previous, perhaps less efficient

একই ক্ষেত্রে প্রযোজ্য fputsবনাম fprintf(কিন্তু fputsসম্পর্কে newline যোগ করে না)।


কোন উপায়ে ব্যবহার printf()কম দক্ষ হবে? রান টাইমে? সংকলন সময়ে?
খোলাখুলি

10
@ রানকালীন সময়ে ফ্র্যাঙ্কলিন, কারণ printfফর্ম্যাট স্ট্রিংটি পার্স করা দরকার। তবে এটি সাধারণত অপ্রাসঙ্গিক হওয়া উচিত। আরও, একটি চতুর সংকলক এটি অনুকূল করতে পারে, এবং printfকলটির সাথে কলটি প্রতিস্থাপন করতে পারেputs
লিওনব্লয়

33

ফর্ম্যাট করা ছাড়াও, putsসফল EOFহলে বা ব্যর্থ হলে একটি অ-নেজিটিভ পূর্ণসংখ্যা প্রদান করে ; যখন printfআয় মুদ্রিত (চিহ্ন নাল ছাড়া) অক্ষরের সংখ্যা।


16

সাধারণ ক্ষেত্রে, সংকলক কলগুলিতে কলগুলিতে রূপান্তর printf()করে puts()

উদাহরণস্বরূপ, নিম্নলিখিত কোডটি আমি পরবর্তী দেখানো সমাবেশ কোডে সংকলিত হবে।

#include <stdio.h>
main() {
    printf("Hello world!");
    return 0;
}
push rbp
mov rbp,rsp
mov edi,str.Helloworld!
call dword imp.puts
mov eax,0x0
pop rbp
ret

এই উদাহরণে, আমি জিসিসি সংস্করণ 4.7.2 ব্যবহার করেছি এবং এর সাথে উত্সটি সংকলন করেছি gcc -o hello hello.c


9
এবং স্ট্যান্ডআউটে জায়গা করে দেয় যে নতুন লাইন সম্পর্কে কি?
zubergu

1
এটি হওয়া উচিত ছিল printf("Hello world!\n");জিসিসি প্রকৃতপক্ষে এটি অনুবাদ করে। যেহেতু এটি একটি পুরানো বার্তা, তাই আমি নিজেই এটি সম্পাদনা করব।
রাফায়েল আলমেদা

2
আপনি সি কোডটি সংকলনের পরে অ্যাসেম্বলি কোডটি কীভাবে পড়লেন?
Koray Tugay

3
@ কোরেতুগায়: জিসিসি-র -save-tempsবিকল্পটি সেটাই করে
স্কাইবা

আপনি বাইনারি বিচ্ছিন্ন করতে gdb এর মতো একটি সরঞ্জামও ব্যবহার করতে পারেন।
ইভান কালায়ানোভ

10

ঠিক আছে, এর printfআরও শক্তিশালী সংস্করণ হিসাবে ভাবা যেতে পারে putsprintfকরার ক্ষমতা উপলব্ধ করা বিন্যাস যেমন আউটপুট ব্যবহার বিন্যাস নির্দিষ্টকরী জন্য ভেরিয়েবল %s, %d, %lf, ইত্যাদি ...


10

আমার অভিজ্ঞতায় বিন্যাসের স্ট্রিং নির্বিশেষে printf()আরও বেশি কোডে থাকা puts()

আমার যদি ফর্ম্যাটিংয়ের প্রয়োজন না হয় তবে আমি ব্যবহার করি না printf। যাইহোক, fwriteথেকে stdoutচেয়ে অনেক দ্রুত কাজ করে puts

static const char my_text[] = "Using fwrite.\n";
fwrite(my_text, 1, sizeof(my_text) - sizeof('\0'), stdout);

দ্রষ্টব্য: প্রতিটি মন্তব্যে, '\ 0' একটি পূর্ণসংখ্যার ধ্রুবক। সঠিক মতামত sizeof(char)মন্তব্য দ্বারা নির্দেশিত হিসাবে হওয়া উচিত ।


2
"স্ট্রাউড টু স্ট্রাউট পুটের তুলনায় অনেক দ্রুত কাজ করে।" - সম্ভবত কারণ কি হতে পারে?
অ্যান্টনি হ্যাচকিন্স

6
@ অ্যান্টনিহ্যাচকিনস এটি সাধারণত "অনেক" দ্রুত হয় না। puts () তবে আপনার স্ট্রিংয়ে প্রতিবার একটি স্ট্রেন () কল করতে হবে যখন আকারটি fwrit () দিয়ে জানা থাকলে এটি এড়ানো যায়। এটি পারফরম্যান্স পার্থক্যের একমাত্র বাস্তব অবদানকারী pretty
Wiz

8
এই উত্তরটি ভুল। '\0'টাইপ আছে int, তাই বেশিরভাগ সিস্টেমে এটি মুদ্রিত হবে Using fwrit। আপনি যদি 1 টি কম বাইট মুদ্রণ করতে চান তবে কেবল 1 ব্যবহার করুন sizeof (char), যা সম্ভবত আপনি এখানে যা চেয়েছিলেন তা নিশ্চিত হবে 1.
ব্র্যাডলি গ্যারাগান

8
int puts(const char *s);

পুটস () স্ট্রিংয়ে স্ট্রাউডে এবং একটি পেছনের নতুন লাইন লিখেছে।

int printf(const char *format, ...);

কাজ প্রিন্টফ () ফর্ম্যাট স্ট্রিংয়ের নিয়ন্ত্রণে স্ট্যান্ডআউটে আউটপুট লেখায় যা আর্গুমেন্টের জন্য কীভাবে পরবর্তী যুক্তি রূপান্তরিত হয় তা নির্দিষ্ট করে।

ডকুমেন্টেশন পড়তে বলার জন্য আমি এই সুযোগটি ব্যবহার করব।


5

প্রিন্টফ () ফাংশনটি স্ক্রিনে উভয় স্ট্রিং এবং ভেরিয়েবল মুদ্রণের জন্য ব্যবহৃত হয় যখন পটস () ফাংশনটি কেবল আপনার পর্দায় একটি স্ট্রিং মুদ্রণের অনুমতি দেয়।


2

puts সহজ পছন্দ এবং শেষের দিকে একটি নতুন লাইন যুক্ত করে এবং printf একটি ফর্ম্যাট স্ট্রিং থেকে আউটপুট লেখেন।

জন্য puts এবং জন্য ডকুমেন্টেশন দেখুনprintf

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


1

তুলনা করার সময় puts()এবং printf(), যদিও তাদের মেমরির খরচ প্রায় একই হয়, puts()তুলনায় বেশি সময় নেয় printf()


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