সি লাইব্রেরির ফাংশনগুলি কি সর্বদা স্ট্রিংয়ের দৈর্ঘ্য আশা করে?


15

আমি বর্তমানে সি-তে লেখা একটি লাইব্রেরিতে কাজ করছি যা এই লাইব্রেরির অনেকগুলি ফাংশন তার যুক্তি হিসাবে char*বা একটি স্ট্রিং আশা করে const char*। আমি সেই ফাংশনগুলি দিয়ে সর্বদা স্ট্রিংয়ের দৈর্ঘ্যের প্রত্যাশা দিয়ে শুরু করি size_tযাতে নাল-সমাপ্তির প্রয়োজন হয় না। যাইহোক, পরীক্ষা লেখার সময়, এর ফলে ঘন ঘন ব্যবহার strlen()যেমন হয়:

const char* string = "Ugh, strlen is tedious";
libFunction(string, strlen(string));

ব্যবহারকারীর যথাযথভাবে শেষ হওয়া স্ট্রিংগুলি পাস করার উপর নির্ভর করা কম নিরাপদ হতে পারে তবে আরও সংক্ষিপ্ত এবং (আমার মতে) পঠনযোগ্য কোড:

libFunction("I hope there's a null-terminator there!");

সুতরাং, এখানে বোধগম্য অনুশীলন কি? ব্যবহারের জন্য এপিআই আরও জটিল করুন, তবে ব্যবহারকারীকে তাদের ইনপুট সম্পর্কে ভাবতে বাধ্য করুন, বা নাল-টার্মিনেটেড স্ট্রিংয়ের জন্য প্রয়োজনীয় প্রয়োজনীয়তা দলিল করুন এবং কলারের উপরে বিশ্বাস করুন?

উত্তর:


4

সুনির্দিষ্টভাবে এবং সম্পূর্ণরূপে দৈর্ঘ্য বহন করে । স্ট্যান্ডার্ড সি লাইব্রেরিটি এইভাবে অবিচ্ছিন্নভাবে ভেঙে গেছে, যার ফলে বাফার ওভারফ্লোগুলি নিয়ে কোনও ব্যাথার শেষ নেই। এই পদ্ধতির এত ঘৃণা এবং যন্ত্রণার কেন্দ্রবিন্দু যে এই আধুনিক স্ট্যান্ডার্ড লাইব্রেরি ফাংশনগুলি ব্যবহার করার সময় আধুনিক সংকলকরা প্রকৃতপক্ষে সতর্ক করে দেবে, ঝকঝকে এবং অভিযোগ করবে।

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

এর আবেগকে একপাশে রেখে, আপনার স্ট্রিংয়ের শেষে এই এনএলএল এর সাথে অনেকগুলি ভুল হতে পারে, এটি পড়তে এবং এটিকে চালিত করতে উভয় ক্ষেত্রেই - প্লাস এটি আধুনিক নকশার ধারণাগুলির যেমন সরাসরি প্রতিরক্ষা-গভীরতায় লঙ্ঘন করছে (অগত্যা সুরক্ষায় প্রয়োগ করা হয়নি, তবে এপিআই ডিজাইনে) সি এ পি আইগুলির উদাহরণ যা দৈর্ঘ্য বহন করে - প্রাক্তন ex উইন্ডোজ এপিআই

প্রকৃতপক্ষে, এই সমস্যাটি 90 এর দশকে একসময় মীমাংসিত হয়েছিল, আজকের উদীয়মান sensক্যমত্য হ'ল আপনার স্ট্রিংগুলি স্পর্শও করা উচিত নয়

পরে সম্পাদনা করুন : এটি বেশ লাইভ বিতর্ক তাই আমি যুক্ত করব যে আপনার নীচে এবং উপরের সবাইকে বিশ্বাস করা ভাল হবে এবং লাইব্রেরি স্ট্রিং * ফাংশনটি ব্যবহার করা ঠিক আছে, যতক্ষণ না আপনি ক্লাসিক স্টাফগুলি দেখতে output = malloc(strlen(input)); strcpy(output, input);বা পছন্দ করেন না while(*src) { *dest=transform(*src); dest++; src++; }। আমি পটভূমিতে মোজার্টের ল্যাকরিমোসা প্রায় শুনতে পারি।


1
উইন্ডোজ এপিআইয়ের আপনার উদাহরণটি আমি বুঝতে পারি না যে কলারের জন্য স্ট্রিংয়ের দৈর্ঘ্য সরবরাহ করতে হবে। উদাহরণস্বরূপ, একটি সাধারণ উইন 32 এপিআই ফাংশন যেমন ইনপুট হিসাবে প্যারামিটার CreateFileনেয় LPTCSTR lpFileName। কলারের কাছ থেকে স্ট্রিংয়ের কোনও দৈর্ঘ্য আশা করা যায় না। প্রকৃতপক্ষে, NUL- টার্মিনেটেড স্ট্রিংগুলির ব্যবহার এতটাই সংক্রামিত যে ডকুমেন্টেশনে এমনকি ফাইলের নামটিও নুল-সমাপ্ত হওয়া উচিত বলে উল্লেখ করা হয়নি (তবে অবশ্যই এটি অবশ্যই হবে)।
গ্রেগ হিউগিল

1
আসলে উইন 32-এ , LPSTRটাইপটি বলে যে স্ট্রিংগুলি NUL- সমাপ্ত হতে পারে এবং যদি তা না হয় তবে এটি সম্পর্কিত স্পেসিফিকেশনে নির্দেশিত হবে। সুতরাং নির্দিষ্টভাবে অন্যথায় নির্দেশিত না হলে, Win32 এ জাতীয় স্ট্রিংগুলি NUL- সমাপ্ত হওয়ার আশা করা হচ্ছে।
গ্রেগ হিউগিল

দারুণ বিষয়, আমি অশুদ্ধ ছিল। বিবেচনা করুন যে ক্রিয়েটফিল এবং এর গুচ্ছটি উইন্ডোজ এনটি 3.1 (90 এর দশকের গোড়ার দিকে) থেকে প্রায়; বর্তমান এপিআই (যেমন এক্সপি এসপি 2-তে মাইক্রোসফ্টের জনসাধারণের ক্ষমা চেয়ে স্টারস্যাফ.এর সূচনা হওয়ার পরে) সমস্ত ন্যূয়েল-টার্মিনেটেড স্টাফকে পরিষ্কারভাবে হ্রাস করেছে। মাইক্রোসফ্ট প্রথমবার নূলে-টার্মিনেটেড স্ট্রিংগুলি ব্যবহার করার জন্য সত্যই দুঃখ পেয়েছিল, যখন ওলকে ২.০ স্পেসিফিকেশনে বিএসটিআর চালু করতে হয়েছিল, যাতে কোনওভাবে একই নৌকায় ভিবি, সিওএম এবং পুরাতন উইনাপি আনতে হয়।
ভিসকি

1
এমনকি StringCbCatউদাহরণস্বরূপ, শুধুমাত্র গন্তব্যটিতে সর্বাধিক বাফার রয়েছে, যা বোঝায়। উৎস এখনও একটি সাধারণ NUL-সমাপ্ত সি স্ট্রিং। কোনও ইনপুট প্যারামিটার এবং আউটপুট প্যারামিটারের মধ্যে পার্থক্য স্পষ্ট করে আপনি নিজের উত্তরটি উন্নত করতে পারেন । আউটপুট পরামিতিগুলির সর্বদা একটি সর্বোচ্চ বাফার দৈর্ঘ্য থাকতে হবে; ইনপুট পরামিতিগুলি সাধারণত নুল-সমাপ্ত হয় (ব্যতিক্রমগুলি রয়েছে তবে আমার অভিজ্ঞতায় বিরল)।
গ্রেগ হিউগিল

1
হ্যাঁ. স্ট্রিংগুলি প্লাটফর্ম স্তরে জেভিএম / ডালভিক এবং। নেট সিএলআর উভয় ক্ষেত্রে এবং সেই সাথে অনেকগুলি ভাষায় অপরিবর্তনীয়। আমি এতদূর গিয়ে অনুমান করতে পারি যে স্থানীয় জগত এখনও এটি করতে পারে না (সি ++ 11 স্ট্যান্ডার্ড) কারণ) ক উত্তরাধিকার (আপনার স্ট্রিংগুলির কেবলমাত্র অংশ অপরিবর্তিত রেখে আপনি এতটা অর্জন করতে পারেন না) এবং খ ) এই কাজটি করার জন্য আপনার সত্যিই একটি জিসি এবং একটি স্ট্রিং টেবিলের প্রয়োজন, সি ++ 11 এ স্কোপড বরাদ্দকারীরা একে একে কাটাতে পারবেন না।
ভিসকি

16

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

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


-1, আমি দুঃখিত, এটি কেবল খারাপ পরামর্শ দেওয়া।
vski

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

4
@vski, বাফার ওভারফ্লো সমস্যা এড়াতে লক্ষ্য ফাংশনটি কল করার আগে ব্যবহারকারীকে কীভাবে 'স্ট্রলেন' কল করতে বাধ্য করে? কমপক্ষে আপনি যদি লক্ষ্য ফাংশনের মধ্যে দৈর্ঘ্য নিজেই পরীক্ষা করেন তবে আপনি নিশ্চিত হতে পারবেন কোন দৈর্ঘ্যের বোধটি ব্যবহৃত হচ্ছে (টার্মিনাল নাল বা না সহ))
চার্লস ই। গ্রান্ট

@ চারেলস ই। গ্রান্ট: স্টারসএফ.ইচ.-এ স্ট্রিংসিবিজিটি এবং স্ট্রিংসিবিটিএনএন সম্পর্কে উপরে মন্তব্য দেখুন। আপনার যদি কেবল একটি চর * এবং দৈর্ঘ্য না থাকে তবে আপনার কাছে আরআরটি * ফাংশন ব্যবহার করা ছাড়া সত্যিকারের পছন্দ নেই, তবে বিন্দুটি দৈর্ঘ্যের চারপাশে বহন করা, সুতরাং এটি স্ট্রিং * এবং স্ট্রেন * এর মধ্যে একটি বিকল্প হয়ে ওঠে দ্বিতীয়টি পছন্দ করা হয় যা ফাংশন।
vski

2
@vski কোনও স্ট্রিংয়ের দৈর্ঘ্য পেরিয়ে যাওয়ার দরকার নেই । সেখানে হয় একটি প্রায় পাস করার প্রয়োজন বাফার এর দৈর্ঘ্য। সমস্ত বাফার স্ট্রিং নয় এবং সমস্ত স্ট্রিং বাফার নয়।
জেমসডলিন

10

আপনার "সুরক্ষা" যুক্তিটি সত্যই ধারণ করে না। আপনি যখন নথিভুক্ত করেছেন (এবং সরল সি এর "আদর্শ" কী) আপনি যদি কোনও নাল-টার্মিনেটেড স্ট্রিং তুলে দেওয়ার জন্য যদি ব্যবহারকারীকে বিশ্বাস না করেন তবে আপনি যে দৈর্ঘ্যটি দিয়েছেন তা আপনি সত্যই বিশ্বাস করতে পারবেন না (যা তারা করবে সম্ভবত strlenযদি আপনি তাদের কাজটি না করেন ঠিক তেমনভাবে ব্যবহার করে পান এবং "স্ট্রিং" প্রথম স্থানে স্ট্রিং না থাকলে যা ব্যর্থ হবে)।

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

এটির জন্য সম্ভবত একটি পারফরম্যান্স দিক রয়েছে। যদি আপনার ফাংশনটির আগেই স্ট্রিংয়ের দৈর্ঘ্যটি জানতে হবে এবং আপনি আশা করেন যে আপনার ব্যবহারকারীরা কমপক্ষে ইতিমধ্যে সেই তথ্যটি জেনে রাখবেন, তাদের তা পাস করে (আপনি এটি গণনা করার চেয়ে) কয়েকটি চক্র নষ্ট করতে পারে।

তবে যদি আপনার গ্রন্থাগারটি সাধারণ সাধারণ ASCII পাঠ্য স্ট্রিংগুলি প্রত্যাশা করে এবং আপনার ব্যবহারকারীরা আপনার গ্রন্থাগারের সাথে কীভাবে যোগাযোগ করবেন তার একটি খুব ভাল বোঝার ক্ষমতা নেই, একটি দৈর্ঘ্যের প্যারামিটার যুক্ত করা কোনও ভাল ধারণা বলে মনে হয় না। যদি স্ট্রিংটি সঠিকভাবে শেষ না করা হয় তবে সম্ভাবনাগুলি দৈর্ঘ্যের পরামিতি ঠিক বোগাসের মতোই হবে। আমি মনে করি না আপনি এটি দিয়ে খুব উপকৃত হবেন।


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

2
আমি বেশিরভাগই আপনার অবস্থানের সাথে একমত , তবে আপনি এই দৈর্ঘ্যের যুক্তিতে অনেক আস্থা রেখেছেন বলে মনে হচ্ছে - নাল টার্মিনেটরের চেয়ে এটি নির্ভরযোগ্য হওয়ার কারণ নেই। আমার অবস্থানটি এটি লাইব্রেরি কী করে তার উপর নির্ভর করে।
মাদুর

মান দ্বারা পাসের দৈর্ঘ্যের চেয়ে স্ট্রিংগুলিতে NULL টার্মিনেটরের সাথে আরও অনেক ভুল হতে পারে। সি-তে, দৈর্ঘ্যের উপর নির্ভর করার একমাত্র কারণ হ'ল এটি অযৌক্তিক এবং অযৌক্তিক হবে - বাফার দৈর্ঘ্য বহন করা ভাল উত্তর নয়, বিকল্পগুলির বিবেচনায় কেবল সেরা। স্ট্রিংগুলি (এবং সাধারণভাবে বাফারগুলি) খুব ভালভাবে প্যাকেটযুক্ত এবং আরএডি ভাষায় এনক্যাপুলেটেড হওয়ার অন্যতম কারণ of
ভিসকি

2

স্ট্রিংগুলি সংজ্ঞা দ্বারা সর্বদা নাল-সমাপ্ত হয়, স্ট্রিংয়ের দৈর্ঘ্য অপ্রয়োজনীয়।

নন-নল-টার্মিনেটেড ক্যারেক্টার ডেটা কখনই "স্ট্রিং" বলা উচিত নয়। এটি প্রক্রিয়া করা (এবং প্রায় দৈর্ঘ্য নিক্ষেপ করা) সাধারণত একটি লাইব্রেরির মধ্যেই এনপ্যাপুলেট করা উচিত , এবং এপিআইয়ের অংশ নয়। কেবলমাত্র একক স্ট্রেলেন () কল এড়াতে প্যারামিটার হিসাবে দৈর্ঘ্যের প্রয়োজন সম্ভবত অকালীন অপটিমাইজেশন।

কোনও এপিআই ফাংশনের কলারের উপর নির্ভর করা নিরাপদ নয় ; নথিভুক্ত পূর্বশর্তগুলি পূরণ না করা হলে অপরিজ্ঞাত আচরণ পুরোপুরি ঠিক।

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


কেবল পুরোপুরি ঠিক আছে তা নয়, তবে প্রকৃতপক্ষে অপরিবর্তনীয় যদি না কেউ মেমরি-নিরাপদ, একক থ্রেডযুক্ত ভাষায় না চলে। আরও কিছু প্রয়োজনীয় নিষেধাজ্ঞাগুলি বাদ পড়েছে ...
প্রতিলিপি

1

আপনার সর্বদা আপনার দৈর্ঘ্য চারপাশে রাখা উচিত। একটির জন্য, আপনার ব্যবহারকারীরা সেগুলিতে ন্যূনগুলি রাখতে চান। এবং দ্বিতীয়ত, strlenও (এন) এটি ভুলে যাবেন না এবং পুরো স্ট্রিংয়ে বাই বাই ক্যাশে স্পর্শ করা দরকার। এবং তৃতীয়ত, সাবটাইটগুলি কাছাকাছি যাওয়া সহজ করে তোলে - উদাহরণস্বরূপ, তারা প্রকৃত দৈর্ঘ্যের চেয়ে কম দিতে পারে।


4
লাইব্রেরির ফাংশনটি এম্বেড করা নুলগুলি স্ট্রিংগুলিতে ডিল করে কিনা তা খুব ভালভাবে নথিভুক্ত করা দরকার। বেশিরভাগ সি লাইব্রেরির ফাংশনগুলি NUL বা দৈর্ঘ্যে বন্ধ হয়, যাহা প্রথম হয় is (এবং যদি দক্ষতার সাথে লিখিত হয় তবে দৈর্ঘ্য নেয় না তারা strlenলুপ পরীক্ষায় কখনও ব্যবহার করে না))
রোবট

1

আপনি একটি স্ট্রিং কাছাকাছি এবং একটি বাফার কাছাকাছি পাস মধ্যে পার্থক্য করা উচিত ।

সি তে, স্ট্রিংগুলি traditionতিহ্যগতভাবে NUL- সমাপ্ত হয়। এটি আশা করা সম্পূর্ণ যুক্তিসঙ্গত। সুতরাং সাধারণত স্ট্রিংয়ের দৈর্ঘ্যের চারপাশে যাওয়ার প্রয়োজন হয় না; এটি strlenপ্রয়োজনীয় হলে এটির সাথে গণনা করা যেতে পারে ।

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

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

(অবিশ্বস্ত উত্স (উদাহরণস্বরূপ একটি নেটওয়ার্ক সকেট) থেকে স্ট্রিং পড়ার ক্ষেত্রে, একটি দৈর্ঘ্য সরবরাহ করা জরুরী যেহেতু ইনপুটটি NUL- সমাপ্ত হতে পারে However তবে আপনাকে ইনপুটটিকে স্ট্রিং হিসাবে বিবেচনা করা উচিত নয় You এটিকে একটি সালিশী ডেটা বাফার হিসাবে বিবেচনা করা উচিত যাতে স্ট্রিং থাকতে পারে (তবে আপনি এটি সত্যায়িত করার আগ পর্যন্ত জানেন না) সুতরাং এটি এখনও নীতির অনুসরণ করে যে বাফারগুলির সাথে সম্পর্কিত আকার থাকতে হবে এবং তারে স্ট্রিংগুলির প্রয়োজন নেই do)


প্রশ্ন এবং অন্যান্য উত্তরগুলি ঠিক এটাই মিস করেছে।
ব্লারফ্লার

0

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

void use_string(char *string, int length);

এক একটি ম্যাক্রো সংজ্ঞায়িত করতে পারে:

#define use_strlit(x) use_string(x, sizeof ("" x "")-1)

এবং তারপরে এটি প্রদর্শিত হিসাবে অনুরোধ করুন:

void test(void)
{
  use_strlit("Hello");
}

যদিও এই ম্যাক্রো সংকলন করবে কিন্তু বাস্তবে কাজ করবে না এমন "সৃজনশীল" জিনিসগুলি নিয়ে আসা সম্ভব হতে পারে, তবে """সাইজফ" এর মূল্যায়নের মধ্যে স্ট্রিংয়ের উভয় পাশের ব্যবহার অক্ষর ব্যবহারের দুর্ঘটনাজনক প্রচেষ্টা ধরা উচিত পচে যাওয়া পংক্তিকৃত ""অক্ষরগুলি বাদ দিয়ে অন্য পয়েন্টারগুলি [সেগুলির অনুপস্থিতিতে , একটি চরিত্রের পয়েন্টারটি পাস করার প্রচেষ্টা ভুলভাবে দৈর্ঘ্যটিকে একটি পয়েন্টারের আকার হিসাবে বিয়োগ করবে min

সি 99 এর বিকল্প পদ্ধতির মধ্যে একটি "পয়েন্টার এবং দৈর্ঘ্য" কাঠামোর ধরণের সংজ্ঞা দেওয়া এবং একটি ম্যাক্রো সংজ্ঞায়িত করা হবে যা একটি স্ট্রিং আক্ষরিককে সেই কাঠামোর ধরণের যৌগিক আক্ষরিক রূপান্তরিত করে। উদাহরণ স্বরূপ:

struct lstring { char const *ptr; int length; };
#define as_lstring(x) \
  (( struct lstring const) {x, sizeof("" x "")-1})

মনে রাখবেন যে কেউ যদি এই জাতীয় দৃষ্টিভঙ্গি ব্যবহার করে তবে তার ঠিকানাগুলি কাছাকাছি না গিয়ে মান দ্বারা এই জাতীয় কাঠামো পাস করা উচিত। অন্যথায় কিছু:

struct lstring *p;
if (foo)
{
  p = &as_lstring("Hello");
}
else
{
  p = &as_lstring("Goodbye!");
}
use_lstring(p);

যৌগিক আক্ষরিক জীবনকাল তাদের বদ্ধ বিবৃতি শেষে শেষ হতে পারে ব্যর্থ হতে পারে।

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