স্ট্রিং সি_স্টার () বনাম তথ্য ()


103

আমি বেশ কয়েকটি স্থানে পড়েছি যে c_str()এবং data()(এসটিএল এবং অন্যান্য বাস্তবায়নে) এর মধ্যে পার্থক্যটি c_str()হ'ল সর্বদা শূন্য হয়ে থাকে যখন data()তা হয় না। যতদূর আমি বাস্তব বাস্তবায়নে দেখেছি, তারা হয় একইভাবে হয় বা data()কল করে c_str()

আমি এখানে কি মিস করছি? কোনটি কোন দৃশ্যে ব্যবহার করা আরও সঠিক?

উত্তর:


109

ডকুমেন্টেশন সঠিক। c_str()আপনি যদি নাল টার্মিনেটেড স্ট্রিং চান তবে ব্যবহার করুন ।

যদি প্রয়োগকারীরা আপনার data()শর্তাবলী বাস্তবায়নে খুশি হয় তবে আপনার যদি c_str()চিন্তা করতে হবে না, data()তবে আপনার যদি স্ট্রিংটি নালটি শেষ করার প্রয়োজন না হয় তবে কিছু ব্যবহারের ক্ষেত্রে এটি সি_এসটার () এর চেয়ে আরও ভাল সম্পাদন করতে পারে।

স্ট্রিংগুলি অগত্যা চরিত্রের ডেটা দিয়ে তৈরি করা উচিত নয়, এগুলি যে কোনও ধরণের উপাদানগুলির সাথে সমন্বিত হতে পারে। সে ক্ষেত্রে data()আরও অর্থবহ হয়। c_str()আমার মতে কেবল তখনই কার্যকর যখন আপনার স্ট্রিংয়ের উপাদানগুলি চরিত্র ভিত্তিক হয়।

অতিরিক্ত : সি ++ 11 এর পরে উভয় ফাংশন একই হওয়ার প্রয়োজন। অর্থাৎ dataএখন নাল-টার্মিনেট করা দরকার। সিপ্রেফারেন্স অনুসারে : "প্রত্যাবর্তিত অ্যারে নাল-টার্মিনেটেড, অর্থাৎ ডেটা () এবং সি_স্ট্রি () একই ফাংশন সম্পাদন করে।"


4
অতিরিক্ত 2: সি ++ 17 এর পরে, এখন নন-কনস্ট্যান্ট ওভারলোডও রয়েছে .data(), তাই তারা আর অ-ধ্রুব স্ট্রিংগুলির সমতুল্য নয়।
Deduplicator

29

ইন সি ++ 11 / সি ++ 0x , data()এবং c_str()এখন আর ভিন্ন। এবং এইভাবে data()শেষে এছাড়াও একটি নাল সমাপ্তি প্রয়োজন।

21.4.7.1 basic_stringঅ্যাক্সেসার্স [স্ট্রিংএ্যাকসেসারস]

const charT* c_str() const noexcept;

const charT* data() const noexcept;

1 রিটার্ন: p + i == &operator[](i)প্রতিটি iইন-এর জন্য একটি পয়েন্টার পি [0,size()]


21.4.5 বেসিক_স্ট্রিং উপাদান অ্যাক্সেস [স্ট্রিং.অ্যাক্সেস]

const_reference operator[](size_type pos) const noexcept;

1 টি প্রয়োজন: পোস্ট <= আকার ()। 2 রিটার্ন: *(begin() + pos) if pos < size()অন্যথায় টির মতো charT();টিয়ের একটি বস্তুর সাথে একটি উল্লেখ রেফারেন্সযুক্ত মানটি সংশোধনযোগ্য হবে না।


যদি স্ট্রিংটি নন-চরিত্রের ডেটা নিয়ে গঠিত, যা স্ট্রিং ডেটা AFAIK এর জন্য আইনী, নাল সহ?
তাজ

4
@taz এমনকি যখন বাইনারি ডেটা সঞ্চয় করার, সি ++ 11 প্রয়োজন যে std::stringএকটি অতিরিক্ত বরাদ্দ charএকটি trailing জন্য '\0'। আপনি std::string s("\0");উভয়ই করেন s.data()[0]এবং উভয়ই s.data()[1]0 পর্যন্ত মূল্যায়নের গ্যারান্টিযুক্ত হন
বিক্রিস্ট

20

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

স্ট্যান্ডিং :: স্ট্রিং ব্যবহারের দুটি কারণ:

std :: স্ট্রিং উভয় পাঠ্য এবং স্বেচ্ছাসেবী বাইনারি তথ্য ব্যবহার করা যেতে পারে।

//Example 1
//Plain text:
std::string s1;
s1 = "abc";

//Example 2
//Arbitrary binary data:
std::string s2;
s2.append("a\0b\0b\0", 6);

উদাহরণস্বরূপ 1 হিসাবে আপনি যখন আপনার স্ট্রিংটি ব্যবহার করছেন তখন আপনার .c_str () পদ্ধতিটি ব্যবহার করা উচিত।

উদাহরণস্বরূপ আপনি যখন আপনার স্ট্রিংটি ব্যবহার করছেন তখন আপনার .data () পদ্ধতিটি ব্যবহার করা উচিত these কারণ এই ক্ষেত্রে .c_str () ব্যবহার করা বিপজ্জনক নয়, তবে এটি অন্যদের জন্য পর্যালোচনা করার ক্ষেত্রে বাইনারি ডেটা নিয়ে কাজ করছেন বলে আরও স্পষ্ট because তোমার গোপন সংকেত.

.ডাটা () ব্যবহার করে সম্ভাব্য সমস্যা

নিম্নলিখিত কোডটি ভুল এবং আপনার প্রোগ্রামে সেগফ্ল্টের কারণ হতে পারে:

std::string s;
s = "abc";   
char sz[512]; 
strcpy(sz, s.data());//This could crash depending on the implementation of .data()

প্রয়োগকারীরা .ডাটা () এবং .c_str () একই জিনিস করা কেন সাধারণ?

কারণ এটি করা আরও দক্ষ। .Data () এমন কিছু ফেরত দেওয়ার একমাত্র উপায় যা বাতিল হওয়া নয়, এটি হবে .c_str () বা .data () এর অভ্যন্তরীণ বাফারটি অনুলিপি করা, বা কেবল 2 টি বাফার ব্যবহার করা। একক নাল টার্মিনেটেড বাফার থাকার অর্থ সর্বদা স্ট্যান্ড :: স্ট্রিং বাস্তবায়নের সময় আপনি কেবলমাত্র একটি অভ্যন্তরীণ বাফার ব্যবহার করতে পারেন।


6
প্রকৃতপক্ষে .data () এর বিন্দুটি হ'ল এটি অভ্যন্তরীণ বাফারটি অনুলিপি করা উচিত নয়। এর অর্থ এটি একটি প্রয়োগকারীর প্রয়োজন হয় যতক্ষণ না until 0 এর উপর চার্জ নষ্ট করতে হয়। আপনি কখনই দুটি বাফার চাইবেন না: আপনি যদি .c_str () কল করেন তবে বাফারে একটি \ 0 যুক্ত করুন। .data () এখনও সেই বাফারটি ফিরিয়ে দিতে পারে।
এমসাল্টাররা

4
সম্পূর্ণরূপে সম্মত হয়েছে 2 টি বাফার ব্যবহার করা হাস্যকর। আপনি কীভাবে জানবেন যে কেন .ডাটা যদিও উদ্দেশ্য ছিল?
ব্রায়ান আর বন্ডি

@ ব্রায়ানআর.বন্ডি আমি এই কোডটি চেষ্টা করেছি: .. অটো আরআর = স্ট্রিং Test "টেস্ট \ 0 স্ট্রিং!" }; কাউট << "ডেটা:" << স্ট্রিংডাটা () << এন্ডল; আউটপুটটি "টেস্ট" এবং পুরো স্ট্রিং নয়, আমি কী ভুল করেছি?
প্রোগ্রামার

শেষ অংশটি ভুল, ডেটা এবং সি_স্ট্রার 0-টার্মিনেট না করে একই বাফারটি ব্যবহার করতে পারে - c_str কেবল প্রথম কলটিতে 0 যুক্ত করতে পারে।
মনিকা

মাথা আপ, সি ++ 11 তৈরি করা হয়েছে .ডাটা () .c_str () এর জন্য একটি নাম
হানশেন্রিক

3

এটি ইতিমধ্যে উত্তর দেওয়া হয়েছে, উদ্দেশ্যে কিছু নোট: বাস্তবায়নের স্বাধীনতা।

std::stringক্রিয়াকলাপগুলি - যেমন পুনরাবৃত্তি, সংমিশ্রণ এবং উপাদান মিউটেশন - শূন্য টার্মিনেটরের প্রয়োজন নেই। আপনি যদি stringশূন্য সমাপ্ত স্ট্রিংয়ের প্রত্যাশা করে কোনও ফাংশনটি পাস না করেন তবে এটি বাদ দেওয়া যাবে।

এটি একটি বাস্তবায়নের জন্য সাবস্ট্রিংগুলিকে আসল স্ট্রিং ডেটা ভাগ করার অনুমতি দেয়: string::substrঅভ্যন্তরীণভাবে স্ট্রিং ডেটার অনুলিপি (এবং অতিরিক্ত বরাদ্দ) এড়ানো, ভাগ করা স্ট্রিং ডেটা এবং প্রারম্ভ / সমাপ্তির পরিসীমা সম্পর্কিত একটি রেফারেন্স রাখতে পারে। আপনি সি_স্টার কল বা স্ট্রিংগুলির কোনওটি সংশোধন না করা পর্যন্ত প্রয়োগটি অনুলিপি স্থগিত করবে। জড়িত স্ট্রিংগুলি কেবল পড়লে কোনও অনুলিপি তৈরি করা হবে না।

(অনুলিপি-সহ লেখার বাস্তবায়ন বহুগঠিত পরিবেশে খুব মজাদার নয়, পাশাপাশি সাধারণ মেমরি / বরাদ্দের সঞ্চয় আজ আরও জটিল কোডের পক্ষে মূল্যবান নয়, তাই এটি খুব কমই সম্পন্ন হয়েছে)।


একইভাবে, string::dataপৃথক অভ্যন্তরীণ উপস্থাপনের অনুমতি দেয় যেমন দড়ি (স্ট্রিং বিভাগগুলির লিঙ্কযুক্ত তালিকা)। এটি কার্যকরভাবে সন্নিবেশ / প্রতিস্থাপনের উন্নতি করতে পারে। আবার, আপনি কল করার সময় c_strবা ভাগ করার পরে বিভাগগুলির তালিকা একক বিভাগে পতন করতে হবে data


2

ANSI ISO IEC 14882 2003(সি ++ 03 স্ট্যান্ডার্ড) এর থেকে উদ্ধৃতি :

    21.3.6 basic_string string operations [lib.string.ops]

    const charT* c_str() const;

    Returns: A pointer to the initial element of an array of length size() + 1 whose first size() elements
equal the corresponding elements of the string controlled by *this and whose last element is a
null character specified by charT().
    Requires: The program shall not alter any of the values stored in the array. Nor shall the program treat the
returned value as a valid pointer value after any subsequent call to a non-const member function of the
class basic_string that designates the same object as this.

    const charT* data() const;

    Returns: If size() is nonzero, the member returns a pointer to the initial element of an array whose first
size() elements equal the corresponding elements of the string controlled by *this. If size() is
zero, the member returns a non-null pointer that is copyable and can have zero added to it.
    Requires: The program shall not alter any of the values stored in the character array. Nor shall the program
treat the returned value as a valid pointer value after any subsequent call to a non- const member
function of basic_string that designates the same object as this.

2

পূর্ববর্তী সমস্ত পদক্ষেপগুলি দৃistence়তাযুক্ত, তবে আমি আরও যুক্ত করতে চাই যে সি ++ 17 থেকে শুরু করে, স্ট্রিংডাটা () কনস্টের চরের পরিবর্তে একটি চর * দেয়


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