আমি একটি std :: স্ট্রিংকে একটি চর * বা চরের [] ডেটা ধরণে রূপান্তর করতে চাই ।
std::string str = "string";
char* chr = str;
ফলাফলগুলিতে: "ত্রুটি: 'std :: স্ট্রিং' কে 'চর' তে রূপান্তর করতে পারে না ..." ।
এটি করার জন্য কোন পদ্ধতি রয়েছে?
আমি একটি std :: স্ট্রিংকে একটি চর * বা চরের [] ডেটা ধরণে রূপান্তর করতে চাই ।
std::string str = "string";
char* chr = str;
ফলাফলগুলিতে: "ত্রুটি: 'std :: স্ট্রিং' কে 'চর' তে রূপান্তর করতে পারে না ..." ।
এটি করার জন্য কোন পদ্ধতি রয়েছে?
উত্তর:
এটি স্বয়ংক্রিয়ভাবে রূপান্তরিত হবে না (thankশ্বরকে ধন্যবাদ)। c_str()
সি স্ট্রিংয়ের সংস্করণ পেতে আপনাকে পদ্ধতিটি ব্যবহার করতে হবে।
std::string str = "string";
const char *cstr = str.c_str();
মনে রাখবেন এটি একটি ফেরত দেয় const char *
; আপনাকে সি-স্টাইলের স্ট্রিং দ্বারা পরিবর্তন করার অনুমতি নেই c_str()
। আপনি যদি এটি প্রক্রিয়া করতে চান তবে আপনাকে প্রথমে এটি অনুলিপি করতে হবে:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
বা আধুনিক সি ++ এ:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
vector
ডায়নামিক অ্যারেগুলির জন্য একটি মোড়ক হিসাবে সুনির্দিষ্টভাবে উদ্ভাবন করা হয়েছিল, সুতরাং এটি ব্যবহার না করা সেরা হারানো সুযোগের মতো বলে মনে হচ্ছে এবং সবচেয়ে খারাপভাবে সি ++ এর স্পিরিটের লঙ্ঘন।
std::string
যা স্বয়ংক্রিয়ভাবে রূপান্তরিত হয়) এবং তারপরে আমি সংক্ষিপ্ত কোডের নমুনা দিয়ে তার কী ব্যবহার করা উচিত তা ব্যাখ্যা করি। সামনের দিকে চিন্তা করে আমি এই ফাংশনটি ব্যবহারের কিছু পার্শ্ব প্রতিক্রিয়াগুলিও ব্যাখ্যা করি, যার মধ্যে একটি হ'ল আপনি যে স্ট্রিংটি দিয়েছিলেন তা সম্পাদনা করতে পারে না c_str()
। আপনি ভুলভাবে আমার সংক্ষিপ্ত উদাহরণগুলি বাস্তব সমস্যা সমাধানের কোড হিসাবে দেখেন যা এটি নয়।
std::vector<char>
)।
আরও বিশদ এখানে এবং এখানে আপনি ব্যবহার করতে পারেন
string str = "some string" ;
char *cstr = &str[0];
আমার যদি সি ++ এর স্ট্রিং সামগ্রীর কোনও মিউটেবল কাঁচা অনুলিপি প্রয়োজন হয় তবে আমি এটি করতাম:
std::string str = "string";
char* chr = strdup(str.c_str());
এবং পরে:
free(chr);
তাহলে আমি কেন অন্য কারোর মতো স্টাড :: ভেক্টর বা নতুন [] দিয়ে ঝাঁকুনি দিচ্ছি না? কারণ যখন আমার কোনও মিউটেবল সি-স্টাইলের কাঁচা চর * স্ট্রিং দরকার, তখন আমি সি কোডটি কল করতে চাই যা স্ট্রিং পরিবর্তন করে এবং সি কোডটি ফ্রি () দিয়ে স্টাফটিকে ডিলোকেট করে এবং ম্যালোক () (স্টার্টআপ ম্যালোক ব্যবহার করে) দিয়ে বরাদ্দ করে । সুতরাং যদি আমি কিছু ফাংশন এক্স আমার কাঁচা স্ট্রিং পাস সি লিখিত এটা পারে এটা যুক্তি উপর একটি বাধ্যতা বা এটির সাথে গাদা বরাদ্দ করেছে (উদাহরণস্বরূপ ফাংশন প্যারামিটার on realloc কল করতে চাইতে পারেন থাকেন)। তবে এটি অত্যন্ত সম্ভাবনা নয় যে এটি নতুন (] কিছু ব্যবহারকারী-নতুন সংজ্ঞায়িত) দিয়ে বরাদ্দকৃত যুক্তির প্রত্যাশা করবে!
strdup
থেকে এসেছে তা আপনার ব্যাখ্যা করা উচিত ।
(এই উত্তরটি কেবলমাত্র C ++ 98 এর জন্য প্রযোজ্য))
দয়া করে, কোনও কাঁচা ব্যবহার করবেন না char*
।
std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
চরটি পয়েন্টারটি কোনও অস্থায়ী হিসাবে না দিয়ে বলা কি ঠিক হবে ?
std::basic_string<>::c_str()
হওয়া অবধি রিটার্নের মান কার্যকর হয় string
is এটি সূচিত করে যে এটি যতক্ষণ string
না সংশোধন করা হয় ততক্ষণ পরবর্তী কলগুলিতে একই মানটি প্রদান করে ।
vector
। আর যদি কোনও RAII প্রক্রিয়া ব্যতীত ব্যতিক্রম-নিরাপদ কোড লিখতে হয় (যেমন, কাঁচা পয়েন্টার ব্যবহার করে), কোড জটিলতা এই সাধারণ ওয়ান-লাইনারের চেয়ে অনেক বেশি হবে।
vector
এতে প্রচুর পরিমাণে ওভারহেড এবং জটিলতা রয়েছে। যদি আপনার প্রয়োজনীয়তাটি হয় যে আপনার একটি পরিবর্তনযোগ্য চর অ্যারে রয়েছে, তবে প্রকৃতপক্ষে চরগুলির একটি ভেক্টর আদর্শ সি ++ র্যাপারের চেয়ে অনেক বেশি। যদি আপনার প্রয়োজনীয়তাটি কেবল একটি কনস্ট-চর পয়েন্টারটির জন্য কল করে তবে কেবল ব্যবহার করুন c_str()
এবং আপনার কাজ শেষ।
আপনি যদি কেবল একই সামগ্রীর প্রতিনিধিত্ব করে একটি সি-স্টাইলের স্ট্রিং চান:
char const* ca = str.c_str();
আপনি যদি নতুন বিষয়বস্তু সহ সি-স্টাইলের স্ট্রিং চান , তবে একটি উপায় (যে আপনি সংকলনের সময় স্ট্রিংয়ের আকারটি জানেন না) তা গতিশীল বরাদ্দ:
char* ca = new char[str.size()+1];
std::copy(str.begin(), str.end(), ca);
ca[str.size()] = '\0';
delete[]
পরে এটি ভুলবেন না ।
আপনি যদি এর পরিবর্তে কোনও স্ট্যাটিকালি-বরাদ্দ, সীমিত দৈর্ঘ্যের অ্যারে চান:
size_t const MAX = 80; // maximum number of chars
char ca[MAX] = {};
std::copy(str.begin(), (str.size() >= MAX ? str.begin() + MAX : str.end()), ca);
std::string
সাধারণ কারণ হিসাবে এটি করা প্রয়োজন সাধারণত ডিজাইনের গন্ধ হিসাবে স্পষ্টভাবে এই ধরণের রূপান্তরিত হয় না। আপনার সত্যই এটি প্রয়োজন তা নিশ্চিত করুন ।
আপনার যদি অবশ্যই একটি প্রয়োজন হয় তবে char*
সবচেয়ে ভাল উপায় সম্ভবত:
vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
&str.front(), &str.back()
(যা সি ++ 03 তে উপস্থিত নেই) আরও সাধারণ str.begin()
এবং এর পরিবর্তে str.end()
?
str.begin()
, বা এমনকি std::begin(str)
, পুনরুক্তি মত? আমি বিশ্বাস করি না যে string
মত স্মৃতিতে থাকার মতো কোনও বাধ্যবাধকতা আছে vector
, নাকি আছে?
&back() + 1
, নয়&back()
বোবোবোর উত্তরের মন্তব্য হিসাবে এটি আরও ভাল হবে তবে আমার কাছে এর জন্য কোন প্রতিনিধি নেই। এটি একই জিনিসটি সম্পাদন করে তবে আরও ভাল অনুশীলনের সাথে।
যদিও অন্যান্য উত্তরগুলি দরকারী, আপনার যদি কখনও বিনষ্ট ছাড়াই স্পষ্টত রূপান্তর std::string
করতে হয় তবে আপনার বন্ধু।char*
const_cast
std::string str = "string";
char* chr = const_cast<char*>(str.c_str());
নোট করুন যে এটি আপনাকে ডেটার একটি অনুলিপি দেবে না ; এটি আপনাকে স্ট্রিংয়ে একটি পয়েন্টার দেবে। সুতরাং, আপনি যদি কোনও উপাদান পরিবর্তন করেন তবে আপনি সংশোধন chr
করবেন str
।
কঠোরভাবে পেডেন্টিক হওয়ার জন্য, আপনি "স্টাডি :: স্ট্রিংকে একটি চর * বা চর [টি] আকারে রূপান্তর করতে পারবেন না।"
অন্যান্য উত্তরগুলি যেমন দেখিয়েছে, আপনি স্টাড :: স্ট্রিংয়ের বিষয়বস্তু একটি চর অ্যারে অনুলিপি করতে পারেন, বা স্ট্যান্ড :: স্ট্রিংয়ের বিষয়বস্তুতে কন্সট চর তৈরি করতে পারেন যাতে আপনি এটি "সি স্টাইল" এ অ্যাক্সেস করতে পারেন ।
আপনি যদি স্টাডি :: স্ট্রিংয়ের বিষয়বস্তু পরিবর্তন করার চেষ্টা করছেন, স্ট্যান্ড :: স্ট্রিং টাইপটিতে আপনার সম্ভবত এটি করার জন্য প্রয়োজন হতে পারে এমন কিছু করার সমস্ত পদ্ধতি রয়েছে।
যদি আপনি এটি কোনও ফাংশনে পাস করার চেষ্টা করছেন যা একটি চর * লাগে, সেখানে স্ট্যান্ড :: স্ট্রিং :: সি_স্ট্রার () রয়েছে।
সম্পূর্ণতার জন্য, ভুলে যাবেন না std::string::copy()
।
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
str.copy(chrs, MAX);
std::string::copy()
NUL সমাপ্ত হয় না। সি স্ট্রিং ফাংশনে ব্যবহারের জন্য যদি আপনাকে কোনও এনইউএল টার্মিনেটর নিশ্চিত করতে হয়:
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
এখানে থেকে আরও একটি শক্তিশালী সংস্করণ Protocol Buffer
char* string_as_array(string* str)
{
return str->empty() ? NULL : &*str->begin();
}
// test codes
std::string mystr("you are here");
char* pstr = string_as_array(&mystr);
cout << pstr << endl; // you are here
if (str[str.length()-1] != 0) str.push_back(0)
ওওপি শৈলীতে রূপান্তর
converter.hpp
class StringConverter {
public: static char * strToChar(std::string str);
};
converter.cpp
char * StringConverter::strToChar(std::string str)
{
return (char*)str.c_str();
}
ব্যবহার
StringConverter::strToChar("converted string")
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());
বিকল্পভাবে, আপনি নীচে প্রদর্শিত হিসাবে লেখার চর * পেতে ভেক্টর ব্যবহার করতে পারেন;
//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .push_back ('\0');
char* cstring = &writable[0] //or &*writable.begin ()
//Goodluck
একটি প্রাপ্ত const char *
একটি থেকে std::string
ব্যবহার c_str()
সদস্য ফাংশন:
std::string str = "string";
const char* chr = str.c_str();
কোনওর char *
থেকে নন-কনস্টেট পেতে std::string
আপনি data()
সদস্য ফাংশনটি ব্যবহার করতে পারেন যা সি ++ 17 এর পরে থেকে কোনও অ-কনস্ট্যান্ট পয়েন্টার দেয়:
std::string str = "string";
char* chr = str.data();
ভাষার পুরানো সংস্করণগুলির জন্য, আপনি স্ট্রিংটি কোনও ভেক্টরে অনুলিপি করতে পরিসীমা নির্মাণ ব্যবহার করতে পারেন যা থেকে কোনও অ-স্থির পয়েন্টার পাওয়া যায়:
std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();
তবে সাবধান হন যে এটি আপনাকে থাকা স্ট্রিংটি সংশোধন করতে দিবে না str
, কেবল অনুলিপিটির ডেটা এভাবেই পরিবর্তন করা যেতে পারে। দ্রষ্টব্য যে c_str()
এখানে ভাষা ব্যবহারের পুরানো সংস্করণগুলিতে এটি বিশেষভাবে গুরুত্বপূর্ণ কারণ এর আগে বলা std::string
না হওয়া অবধি সমাপ্ত হওয়ার গ্যারান্টি ছিল না c_str()
।
এটিও কাজ করবে
std::string s;
std::cout<<"Enter the String";
std::getline(std::cin, s);
char *a=new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());
std::cout<<a;
c_str
উন্মাদনাটিকে পুরোপুরি এড়িয়ে চলবে ।