নন-নাল টার্মিনেটেড স্ট্রিং সহ প্রিন্টফ ব্যবহার করা


107

মনে করুন আপনার কাছে একটি স্ট্রিং রয়েছে যা nullশেষ হয়নি এবং আপনি তার সঠিক আকারটি জানেন, সুতরাং আপনি কীভাবে সেই স্ট্রিংটি printfসি দিয়ে মুদ্রণ করতে পারেন ? আমি এরকম একটি পদ্ধতি স্মরণ করি তবে আমি এখনই খুঁজে পাচ্ছি না ...


9
ইন Cকনটেক্সট, সমস্ত স্ট্রিং নাল সমাপ্ত হয়। এগুলির মধ্যে একটি শূন্য ছাড়াই চরের অ্যারেগুলি স্ট্রিং নয় ... তারা চরের অ্যারে :)
pmg


উত্তর:


174

প্রিন্টফের সাথে একটি সম্ভাবনা রয়েছে, এটি এরকম হয়:

printf("%.*s", stringLength, pointerToString);

কোনও কিছু অনুলিপি করার দরকার নেই, মূল স্ট্রিং বা বাফারটি সংশোধন করার দরকার নেই।


10
কিন্তু এটিকে যেকোনোভাবে বিপদজনক, কারো কোনদিন% s এর সাথে এই স্ট্রিং printf হবে
pmod

6
@ পডমোড: অগত্যা বাফারটি যদি বাইরের বিশ্বের সংস্পর্শে না আসে তবে অগত্যা। এটি কেবল স্ট্রিংয়ের কিছু অংশ মুদ্রণের জন্যও খুব দরকারী (এটি অবশ্যই বাতিল হতে পারে)। আপনি যদি বাস্তবে এটি কার্যকরভাবে দেখতে চান তবে ওপেনসার / কমাইলিও এসআইপি প্রক্সিটি দেখুন যেখানে তারা এই কৌশলটির কারণে স্টাফ অনুলিপি করা এড়াতে পারে (এছাড়াও স্প্রিন্টফ ব্যবহার করে)।
ডার্কডাস্ট

6
অন্য +1। আমি যখন এটি প্রায় printfএক দশক পরেও যেমন মৌলিক জিনিসগুলি সম্পর্কে জিনিসগুলি শিখি তখন আমি এটি পছন্দ করি ... :)
হার্টজেল গিনেস

1
আমার পক্ষে এটি খুব কার্যকর যখন আমি কোনও এপিআই থেকে নন-নাল টার্মিনেটেড স্ট্রিং পাই (কিছু উইন্ডোজ এপিআই এটি করে!) এবং এটি 'যুক্তিসঙ্গত' উপায়ে ফেরত দিতে হয়। । সুতরাং:% দীর্ঘ জীবন * গুলি (। অথবা% * এস যা রূপান্তর ইউনিকোড করতে হবে <-> তোমার জন্য একক বাইট;))
FrizzTheSnail

3
@ ব্যবহারকারী ১৪৪৪739৯: আপনার ক্ষেত্রে printf১১ টি অক্ষর মুদ্রিত হবে বা যতক্ষণ না প্রথমে আসে তার সাথে NULL এর মুখোমুখি হবে; আপনার উদাহরণে NULL প্রথম আসে। সর্বাধিক দৈর্ঘ্য উল্লেখ করা NULL এর "শেষ-স্ট্রিং" অর্থটি হারাবে না printf
ডার্কডাস্ট

29

এখানে কীভাবে %.*sকাজ করে তার ব্যাখ্যা এখানে দেওয়া হয়েছে ।

একটি প্রিন্টফ টেমপ্লেট স্ট্রিংয়ের রূপান্তরকরণের স্পেসিফিকেশনের সাধারণ ফর্ম রয়েছে:

% [ param-no $] flags width [ . precision ] type conversion

অথবা

% [ param-no $] flags width . * [ param-no $] type conversion

দ্বিতীয় ফর্মটি আর্গুমেন্ট তালিকা থেকে নির্ভুলতা পাওয়ার জন্য:

আপনি '*' এর যথার্থতাও নির্দিষ্ট করতে পারেন। এর অর্থ হ'ল আর্গুমেন্ট তালিকার পরবর্তী যুক্তিটি (প্রকৃত মান মুদ্রণের আগে) যথার্থ হিসাবে ব্যবহৃত হয়। মানটি অবশ্যই একটি আন্ত হতে হবে এবং এটি নেতিবাচক হলে তা এড়ানো হবে।

আউটপুট রূপান্তর বাক্য গঠন গ্লিবিসি ম্যানুয়ালটিতে

জন্য %sস্ট্রিং বিন্যাসন, স্পষ্টতা একটি বিশেষ অর্থ রয়েছে:

সর্বাধিক সংখ্যক অক্ষর লেখার জন্য একটি নির্ভুলতা নির্দিষ্ট করা যেতে পারে; অন্যথায় স্ট্রিংয়ের মধ্যে অক্ষরগুলি শেষ হওয়া নাল অক্ষর সহ আউটপুট প্রবাহে লেখা হয়।

অন্যান্য আউটপুট রূপান্তর গ্লিবিসি ম্যানুয়ালটিতে

অন্যান্য দরকারী রূপগুলি:

  • "%*.*s", maxlen, maxlen, val ডান ন্যায়সঙ্গত করা হবে, স্পেস আগে beforeোকানো;
  • "%-*.*s", maxlen, maxlen, val বাম-ন্যায়সঙ্গত হবে।

যদি আমি সঠিকভাবে বুঝতে পারি তবে নীচেরগুলি আউটপুটটিকে প্যাড করবে তবুও কোনও স্ট্রিং ওভারফ্লো প্রতিরোধ করবে? "%-*.*s", padding, str_view.size(), str_view.data()
scx

20

আপনি stdout একটি fwrit () ব্যবহার করতে পারেন!

fwrite(your_string, sizeof(char), number_of_chars, stdout);

এই পদ্ধতিতে আপনি প্রথম অক্ষরটিকে (একটি ফাইলের সাথে সংখ্যার_সংখ্যার_চর্চায় পরিবর্তনশীল সংখ্যায়) আউটপুট দেবেন, এক্ষেত্রে স্টাডআউটে (স্ট্যান্ডার্ড আউটপুট, আপনার স্ক্রিন)!


2
আপনি যখন স্ট্রিং এবং জিরো সমন্বিত দীর্ঘ বাফারটি পরিদর্শন করতে চান তখন খুব সহায়ক!
এলিস্ট

13

printf("%.*s", length, string) কাজ করবে না.

এর অর্থ দৈর্ঘ্য বাইট বা একটি নাল বাইট, যেটি প্রথমে আসে মুদ্রণ করা। যদি আপনার নন-নল-টার্মিনেটেড অ্যারে অফ-চর দৈর্ঘ্যের আগে নাল বাইট থাকে তবে প্রিন্টফ সেগুলি বন্ধ হয়ে যাবে এবং চালিয়ে যাবে না।


4
এবং এটি কীভাবে ওপির প্রশ্নের উত্তর?
শাহবাজ

12
যদি এটি নাল-টার্মিনেটেড না হয় তবে নুলটি স্ট্রিংটি ধারণের জন্য একটি বৈধ অক্ষর। এটি এখনও অ্যারে নাল-টার্মিনেটেড বলে মনে করে, এটি কেবল এটি দীর্ঘতর অ্যারে হিসাবে বিবেচনা করে যা এটি থেকে সাব-সিলেক্ট করা হচ্ছে - যার অর্থ যদি আপনার যদি এটিতে নাল দিয়ে স্ট্রিং থাকে তবে এটি সমস্যার সৃষ্টি করবে।
লাহরন

3
printf("%.5s", pointerToNonNullTerminatedString);

স্ট্রিং দৈর্ঘ্য হবে 5।


1
#include<string.h> 
int main()
{
/*suppose a string str which is not null terminated and n is its length*/
 int i;
 for(i=0;i<n;i++)
 {
 printf("%c",str[i]);
 }
 return 0;
}

আমি কোডটি সম্পাদনা করেছি, এখানে অন্যভাবে:

#include<stdio.h>
int main()
{
printf ("%.5s","fahaduddin");/*if 5 is the number of bytes to be printed and fahaduddin is the string.*/

return 0;

}

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

@ ডার্কডাস্ট: কেবলমাত্র একটি প্যাথলজিকাল মেশিনই শব্দের সীমানায় আবদ্ধ না হয়ে বাইট পাঠের শাস্তি দেয়। আপনি কি শব্দ ভাবছেন শব্দের সীমানায় আবদ্ধ নয়? নাকি কিছু প্রাচীন মিপস জঞ্জাল বা কিছু?
আর .. গিথহাব বন্ধ করুন ICE

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

@ ডার্কডাস্ট: বাইট রিডের জন্য আপনি এটি সম্পর্কে সম্পূর্ণ ভুল। কেন আপনি একটি বেঞ্চমার্ক করবেন না? x86 এর সম্পূর্ণ পারমাণবিক বাইট অপারেশন রয়েছে এবং সর্বদা ছিল। এটি শব্দের আকারের অংশগুলি আনে না (ক্যাশে স্তর ব্যতীত, যা অনেক বড় অংশ নিয়ে আসে এবং প্রান্তিককরণ অপ্রাসঙ্গিক, তবে আমি ইতিমধ্যে ক্যাশেড ডেটা নিয়ে কথা বলছি)।
আর .. গিথহাব থামিয়ে দিন IEL

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