ফাংশনগুলি ফিরছে স্ট্রিং, ভাল স্টাইল?


11

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

char * mytype_to_string( const mytype_t *t );

আমি আসলে বুঝতে পারি যে স্ট্রিংটি ফিরে আসার জন্য স্মৃতি পরিচালনা করার জন্য আমার কাছে এখানে কমপক্ষে তিনটি বিকল্প রয়েছে (কমপক্ষে))

বিকল্প 1: ফাংশনে স্ট্যাটিক চর অ্যারেতে রিটার্ন স্ট্রিং সংরক্ষণ করে। প্রতিটি কলটিতে স্ট্রিংটি ওভাররাইট করা বাদে আমার বেশি চিন্তাভাবনা করার দরকার নেই। যা কিছু অনুষ্ঠানে সমস্যা হতে পারে।

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

বিকল্প 3: একটি বাফারে পয়েন্টারে পাস করুন, এবং কলারকে সেই বাফার বরাদ্দ দিন। ভালো লেগেছে:

char * mytype_to_string( const mytype_t *mt, char *buf, size_t buflen ); 

এটি কলারের আরও প্রচেষ্টা নিয়ে আসে। আমি আরও লক্ষ্য করি যে এই বিকল্পটি আমাকে যুক্তিগুলির ক্রম হিসাবে একটি অন্য বিকল্প দেয়। আমার প্রথম এবং শেষটি কোন যুক্তিযুক্ত হওয়া উচিত? (আসলে ছয়টি সম্ভাবনা)

তাহলে, আমার কোনটি পছন্দ করা উচিত? কেন? সি বিকাশকারীদের মধ্যে কি কোনও ধরনের অলিখিত মান রয়েছে?


3
কেবল একটি পর্যবেক্ষণমূলক নোট, বেশিরভাগ অপারেটিং সিস্টেমগুলি বিকল্প 3 ব্যবহার করে - কলার যেভাবেই বাফার বরাদ্দ করে; বাফার পয়েন্টার এবং ক্ষমতা বলে; কলি বাফার পূরণ করে এবং বাফার অপর্যাপ্ত থাকলে স্ট্রিংয়ের প্রকৃত দৈর্ঘ্যও প্রদান করে । উদাহরণ: sysctlbynameওএস এক্স এবং আইওএসে
রোবং

উত্তর:


11

আমি সবচেয়ে বেশি যে পদ্ধতিগুলি দেখেছি তা হ'ল 2 এবং 3।

ব্যবহারকারীর সরবরাহিত বাফারটি ব্যবহার করা আসলে বেশ সহজ:

char[128] buffer;
mytype_to_string(mt, buffer, 128);

যদিও বেশিরভাগ বাস্তবায়নগুলি ব্যবহার করা বাফারের পরিমাণটি ফিরিয়ে দেবে।

বিকল্প 2 ধীর হবে এবং গতিশীল লিঙ্কযুক্ত লাইব্রেরিগুলি যেখানে তারা বিভিন্ন রানটাইম (এবং বিভিন্ন হিপ) ব্যবহার করতে পারে তা ব্যবহার করার সময় বিপজ্জনক। সুতরাং অন্য লাইব্রেরিতে যা খারাপ হয়েছে তা আপনি মুক্ত করতে পারবেন না। এরপরে free_string(char*)এটি মোকাবেলা করার জন্য একটি ফাংশন প্রয়োজন ।


ধন্যবাদ! আমার মনে হয় আমি বিকল্প 3ও পছন্দ করি। তবে আমি এই জাতীয় জিনিসগুলি করতে সক্ষম হতে চাই: printf("MyType: %s\n", mytype_to_string( mt, buf, sizeof(buf));এবং তাই আমি ব্যবহৃত দৈর্ঘ্যটি বরং স্ট্রিংটিতে পয়েন্টারটি ফিরিয়ে দিতে চাই না। গতিশীল লাইব্রেরির মন্তব্যটি সত্যই গুরুত্বপূর্ণ।
inসিস্টিন শানিং-জোহানসেন

এটি কি টার্মিনেটর sizeof(buffer) - 1সন্তুষ্ট করা উচিত নয় \0?
মাইকেল-ও

1
@ মাইকেল-ও, নাল শব্দটি বাফার আকারে অন্তর্ভুক্ত করা হয়নি যার অর্থ সর্বাধিক স্ট্রিং যা রাখা যেতে পারে তা আকারের পাসের চেয়ে 1 কম। snprintfব্যবহারের মতো স্ট্যান্ডার্ড লাইব্রেরিতে সুরক্ষিত স্ট্রিংটি এটি নিদর্শন ।
ratchet freak

@ratchetfreak পরিষ্কার করার জন্য ধন্যবাদ। উত্তরটি প্রজ্ঞার সাথে প্রসারিত করতে ভাল লাগবে।
মাইকেল-ও

0

# 3 এর জন্য অতিরিক্ত নকশা ধারণা

সম্ভব হলে, mytypeএকই .h ফাইলের জন্য প্রয়োজনীয় সর্বোচ্চ আকারটি সরবরাহ করুন mytype_to_string()

#define MYTYPE_TO_STRING_SIZE 256

এখন ব্যবহারকারী সেই অনুযায়ী কোড করতে পারেন।

char buf[MYTYPE_TO_STRING_SIZE];
puts(mytype_to_string(mt, buf, sizeof buf));

ক্রম

অ্যারের আকার, যখন প্রথম, ভিএলএ প্রকারের জন্য অনুমতি দেয়।

char * mytype_to_string( const mytype_t *mt, size_t bufsize, char *buf[bufsize]); 

একক মাত্রার সাথে এত গুরুত্বপূর্ণ নয়, তবে 2 বা ততোধিকের সাথে দরকারী।

void matrix(size_t row, size_t col, double matrix[row][col]);

আমার মনে আছে প্রথম সাইজটি পড়া পরের সিতে একটি পছন্দসই প্রতিমা id সেই রেফারেন্সটি খুঁজে পাওয়া দরকার ...


0

@ র‌্যাচেটফ্রেকের দুর্দান্ত উত্তরের যোগ হিসাবে আমি উল্লেখ করব যে বিকল্প # 3 মান সি লাইব্রেরির ক্রিয়াকলাপ হিসাবে একই ধরণের দৃষ্টান্ত / প্যাটার্ন অনুসরণ করে।

উদাহরণস্বরূপ strncpy,।

char * strncpy ( char * destination, const char * source, size_t num );

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

আপনার পোস্টে যা রয়েছে তার সাথে কেবলমাত্র পার্থক্যটি destinationহ'ল সি লাইব্রেরিতে আর্গুমেন্টটি প্রথমে যুক্তি তালিকার তালিকাভুক্ত হতে থাকে। তাই:

char * mytype_to_string( char *buf, const mytype_t *mt, size_t buflen ); 

-2

আপনি যা করার প্রস্তাব দিচ্ছেন তা একটি খারাপ কোড গন্ধ, এই বিকল্পটি 3 আমার কাছে সবচেয়ে ভাল লাগে। আমি @ gnasher729 এর মতও মনে করি যে আপনি ভুল ভাষা ব্যবহার করছেন।


আপনি একটি কোড গন্ধ ঠিক কি বিবেচনা? সম্প্রসারিত করুন.
হাল্ক

-3

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

আপনি সি ++ বা অবজেক্টিভ-সি বিবেচনা করতে পারেন যেখানে আপনি আপনার কোডের 99% অপরিবর্তিত রাখতে পারবেন।

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