std :: string to char *


335

मैं एक std :: string को char * या char [] में बदलना चाहता हूं। data type ।

std::string str = "string";
char* chr = str;

का परिणाम: "त्रुटि: 'एसटीडी :: स्ट्रिंग' को 'चार' में परिवर्तित नहीं किया जा सकता ..."

ऐसा करने के लिए कौन से तरीके उपलब्ध हैं?

c++  string  char 

जवाबों:


671

यह स्वचालित रूप से परिवर्तित नहीं होगा (भगवान का शुक्र है)। c_str()C स्ट्रिंग संस्करण प्राप्त करने के लिए आपको विधि का उपयोग करना होगा ।

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;

या आधुनिक C ++ में:

std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);

4
@ केरेक एसबी: यह एक उदाहरण था, वास्तविक कोड में एक स्मार्ट पॉइंटर का उपयोग करेगा, या अधिक संभावना है कि इस c_strपागलपन से पूरी तरह से बचें ।
१p

14
जवाब भारी, असभ्य, गैर-स्थानीय है, कच्चे सरणियों का उपयोग करता है, और अपवाद सुरक्षा पर ध्यान देने की आवश्यकता है। vectorगतिशील सरणियों के लिए एक आवरण के रूप में ठीक से आविष्कार किया गया था, इसलिए इसका उपयोग नहीं करना सबसे अच्छा समय में एक छूटे हुए अवसर की तरह लगता है, और सबसे खराब रूप से C ++ की भावना का उल्लंघन है।
केरेक एस.बी.

21
सबसे पहले, हाँ भारी जवाब है। पहले मैं ओपी की त्रुटि (यह सोचकर कि std::stringस्वचालित रूप से परिवर्तित हो जाएगी) समझाता हूं और फिर मैं समझाता हूं कि उसे क्या उपयोग करना चाहिए, एक छोटे कोड के नमूने के साथ। आगे सोचते हुए मैं इस फ़ंक्शन के उपयोग के कुछ दुष्प्रभावों की व्याख्या करता हूं, जिनमें से एक यह है कि आप द्वारा दिए गए स्ट्रिंग को संपादित नहीं कर सकते हैं c_str()। आप गलती से मेरे छोटे उदाहरणों को वास्तविक समस्या-समाधान कोड के रूप में देखते हैं, जो यह नहीं है।
orlp

8
मैंने जवाब ठुकरा दिया। यह उत्तर वास्तव में उपयोगी नहीं है और इस तथ्य को स्वीकार किया गया कि यह सबसे दुर्भाग्यपूर्ण है। यह उत्तर पूरी तरह से अच्छे C ++ प्रोग्रामिंग प्रथाओं और अपवाद सुरक्षा की अवहेलना करता है और वहाँ बहुत बेहतर समाधान हैं, जिनमें से कुछ इस प्रश्न के अन्य उत्तरों में दिए गए हैं (जैसे कि ildjarn द्वारा दिया गया उत्तर जो उपयोग करता है std::vector<char>)।
जेम्स मैकनेलिस

114
@ james-mcnellis, मैंने इस उत्तर को सही के रूप में चुना क्योंकि यह वास्तव में उत्तर देता है कि मैं क्या पूछ रहा था ... और नहीं, कम नहीं। मैंने यह नहीं पूछा कि आपको क्या लगता है कि मुझे क्या करना चाहिए, मैंने एक अलग समाधान के लिए नहीं पूछा कि आप क्या सोचते हैं कि मैं कर रहा हूं, मैंने अच्छी प्रथाओं के लिए नहीं पूछा। आपको पता नहीं है कि मैं क्या काम कर रहा हूं, मेरा कोड कहां और किन परिस्थितियों में लागू होने वाला है। कुछ को पढ़ना, प्रश्नों को समझना और वास्तव में जो पूछा जा रहा है, उसका उत्तर देना सीखना चाहिए। यहां दिखाने की जरूरत नहीं है।

150

अधिक विवरण यहां , और यहां लेकिन आप उपयोग कर सकते हैं

string str = "some string" ;
char *cstr = &str[0];

15
एफडब्ल्यूआईडब्ल्यू, मेरी पुस्तक में, इस सवाल का एकमात्र सही उत्तर है जो वास्तव में पूछा गया था। एक std :: string स्वाभाविक रूप से उत्परिवर्तनीय है: जो लोग इसे साउंड बना रहे हैं जैसे स्ट्रिंग की सामग्री को संशोधित करना किसी तरह शैतान का काम इस तथ्य को याद नहीं करता है।
जे। फ्रीमैन -सौरिक-

2
हां, यह सही उत्तर है। यह मूर्खतापूर्ण है कि, उपयोग की आवृत्ति को देखते हुए, ऐसा करने के लिए एक standart विधि नहीं है, जैसे msoft की लॉकबफ़र।
एरिक एरोनेस्टी

1
मैंने 0 से 0u बदल दिया। क्योंकि कुछ कंपाइलर्स / लाइब्रेरीज़ (इस पर विश्वास करें या न करें) कुछ अस्पष्टता के बारे में शिकायत करते हैं जब चेतावनियों को चालू करने के लिए पूरे रास्ते को बंद कर दिया जाता है [0] निर्माण
एरिक एरोनिटी

मुझे संदेह है कि जब तार को हटा दिया जाता है, तो चारो तरफ अशक्त बना दिया जाता है। इसलिए मुझे लगता है कि केवल स्ट्रिंग के एक सूचक को चार सूचक को सौंपा गया है। तो स्ट्रिंग टू चर का रूपांतरण वस्तुतः पूर्ण नहीं है। स्ट्रिंग केवल चार * की ओर इंगित की गई है, लेकिन इसका मान परिवर्तित नहीं है। क्या मैं सही हूँ???
समिथा चतुरंग

5
ध्यान दें कि यह केवल C ++ 11 है। पिछले संस्करणों में निरंतर भंडारण नहीं हो सकता है या समाप्त हो रहा है अशक्त
Flamefire

40

अगर मुझे एक c ++ स्ट्रिंग सामग्री की एक पारस्परिक कच्ची प्रतिलिपि की आवश्यकता होगी, तो मैं यह करूँगा:

std::string str = "string";
char* chr = strdup(str.c_str());

और बादमें:

free(chr); 

तो मैं किसी और की तरह std :: वेक्टर या नए [] के साथ फील क्यों नहीं करता? क्योंकि जब मुझे एक परस्पर सी-स्टाइल कच्चे चार * स्ट्रिंग की आवश्यकता होती है, तो क्योंकि मैं सी कोड को कॉल करना चाहता हूं जो स्ट्रिंग को बदलता है और सी कोड नि: शुल्क () के साथ सामान को आवंटित करता है और मॉलोक () के साथ आवंटित करता है (स्ट्रैपअप मॉलोक का उपयोग करता है) । इसलिए अगर मैं C में लिखे कुछ फंक्शन X में अपना कच्चा तार पास करता हूँ, तो हो सकता है कि उस पर यह तर्क हो कि उसे ढेर पर आवंटित किया जाना है (उदाहरण के लिए यदि फ़ंक्शन पैरामीटर पर realloc कॉल करना चाहता है)। लेकिन इसकी बहुत संभावना नहीं है कि यह (कुछ उपयोगकर्ता-पुनर्परिभाषित) नए [] के साथ आवंटित तर्क की उम्मीद करेगा!


आपको समझाना चाहिए कि कहां strdupसे है।
LF

22

(यह उत्तर केवल 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*

1
मुझे वास्तव में आज पहले जैसा कुछ चाहिए था। मैं सोच रहा था, क्या यह कहना ठीक है कि vector<char>(str.c_str(), str.c_str() + str.size() + 1)बिना चैरिटी के लिए चार पॉइंटर दिए गए हैं?
केरेक एसबी

1
@ केरैक: हां, बदले या नष्ट std::basic_string<>::c_str()होने तक का रिटर्न वैल्यू मान्य stringहै। इसका अर्थ यह भी है कि यह बाद की कॉल पर समान मूल्य लौटाता है जब तक stringसंशोधित नहीं किया जाता है।
.िलजर्न

2
@ फ्रिट्ज़िस: vectorइस तरह से इस्तेमाल करने की कोई गति या जगह नहीं है । और अगर कोई आरएआई तंत्र के बिना अपवाद-सुरक्षित कोड लिखता था (यानी, कच्चे पॉइंटर्स का उपयोग करके), तो कोड जटिलता इस सरल वन-लाइनर की तुलना में बहुत अधिक होगी।
.िलजर्न

7
यह एक मिथक है vectorजिसमें भारी मात्रा में सिर और जटिलता है। यदि आपकी आवश्यकता यह है कि आपके पास एक परिवर्तनशील चार सरणी है, तो वास्तव में एक वेक्टर ऑफ़ चर बहुत अधिक आदर्श सी ++ आवरण है। यदि आपकी आवश्यकता वास्तव में सिर्फ एक कॉन्स्ट-चार पॉइंटर के लिए कहती है, तो बस उपयोग करें c_str()और आप कर रहे हैं।
केरेक एसबी

3
@ मिल्डजर्न: असल में, यह मूल रूप से था
ऑर्बिट

15
  • यदि आप एक ही सामग्री का प्रतिनिधित्व करने वाले सी-स्टाइल स्ट्रिंग चाहते हैं:

    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

1
क्यों &str.front(), &str.back()(जो C ++ 03 में मौजूद नहीं है) अधिक सामान्य str.begin()और के बजाय str.end()?
आर्मेन सुनायुन

1
क्या के बारे में str.begin(), या यहाँ तक कि std::begin(str), इट्रेटर की तरह? मेरा मानना stringहै कि किसी भी तरह की स्मृति में होना दायित्व है vector, या है?
xtofl

1
@xtofl: मैंने पहले ही उन लोगों को संपादित कर दिया है और हां, C ++ 11 के रूप में एक दायित्व है; यह C ++ 03 में निहित था।
ऑर्बिट

@xtofl: C ++ 03 में नहीं। C ++ 11 में हमारे पास वह गारंटी है, साथ में सामने () और पीछे () फ़ंक्शंस हैं, जिनका वैसे भी मूल उत्तर में दुरुपयोग किया गया था
Armen Tsirunyan

1
@ टोमलाक: उनका दुरुपयोग किया गया था जिसमें आपको जरूरत थी &back() + 1, न कि&back()
आर्मेन स्यिरुयान

12

यह बॉबोबोबो के उत्तर पर एक टिप्पणी के रूप में बेहतर होगा, लेकिन मेरे पास इसके लिए प्रतिनिधि नहीं है। यह एक ही चीज़ को पूरा करता है लेकिन बेहतर प्रथाओं के साथ।

हालांकि अन्य उत्तर उपयोगी होते हैं, अगर आप कभी भी बदलने की आवश्यकता std::stringके लिए char*स्थिरांक बिना स्पष्ट रूप से, const_castअपने दोस्त है।

std::string str = "string";
char* chr = const_cast<char*>(str.c_str());

ध्यान दें कि यह आपको डेटा की प्रतिलिपि नहीं देगा; यह आपको स्ट्रिंग के लिए एक संकेतक देगा। इस प्रकार, यदि आप किसी तत्व को संशोधित करते हैं, तो आप संशोधित chrकरेंगे str


7

यह मानते हुए कि इनपुट के रूप में पास होने के लिए आपको बस एक सी-स्टाइल स्ट्रिंग की आवश्यकता है:

std::string str = "string";
const char* chr = str.c_str();

5

कड़ाई से पांडित्यपूर्ण होने के लिए, आप "एक std :: string को char * या char [] डेटा प्रकार में नहीं बदल सकते।"

जैसा कि अन्य उत्तरों में दिखाया गया है, आप std की सामग्री :: स्ट्रिंग को चार सरणी में कॉपी कर सकते हैं, या std :: string के कंटेंट में एक कॉस्ट चार * बना सकते हैं ताकि आप इसे "C स्टाइल" में एक्सेस कर सकें। ।

यदि आप std :: string की सामग्री को बदलने की कोशिश कर रहे हैं, तो std :: string प्रकार में कुछ भी करने की विधियाँ हैं, जो संभवतः आपको करने की आवश्यकता हो सकती है।

यदि आप इसे किसी फंक्शन में ले जाने की कोशिश कर रहे हैं, जो एक चार * लेता है, तो वहाँ है std :: string :: c_str ()।


4

पूर्णता के लिए, मत भूलना std::string::copy()

std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];

str.copy(chrs, MAX);

std::string::copy()एनयूएल समाप्त नहीं करता है। यदि आपको C स्ट्रिंग फ़ंक्शंस में उपयोग के लिए NUL टर्मिनेटर सुनिश्चित करने की आवश्यकता है:

std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];

memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);

4

यहाँ से एक और अधिक मजबूत संस्करण है 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

+1 यह जाँचने के लिए कि स्ट्रिंग खाली है। मैं यह सुनिश्चित करने के लिए एक जांच भी if (str[str.length()-1] != 0) str.push_back(0)
जोड़ूंगा

4

OOP शैली में रूपांतरण

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")

मुझे पसंद है कि कैसे चार को कास्ट * c_str के आउटपुट से कास्ट को समाप्त करता है, मुझे लगता है कि कारण c_str रिटर्न कास्ट char * संभावित मेमोरी एक्सेस के मुद्दों को खत्म करने के लिए है, चीज का केवल एक रीड वर्जन प्रदान करके। ओपी एक चार * लेना चाहता है, लेकिन मुझे लगता है कि वह इसके बजाय c_str के const char * आउटपुट द्वारा बेहतर सेवा दे सकता है, क्योंकि यह सुरक्षित है, और फ़ंक्शन जो char * को लेते हैं, आमतौर पर const char * लेते हैं और साथ ही साथ (मान लेते हैं कि कार्य नहीं करते हैं) उनके इनपुट को बदलने की तरह कुछ भी करें, जो सामान्य रूप से, उन्हें नहीं करना चाहिए)।
फेलिप वैलेड्स


3

वैकल्पिक रूप से, आप नीचे दिए गए प्रदर्शन के अनुसार वैक्टर का उपयोग कर सकते हैं *

//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  

यह वेक्टर के लिए नई मेमोरी आवंटित करेगा और फिर प्रत्येक वर्ण को कॉपी करेगा। std :: string पहले से ही एक कंटेनर है, आप अपने स्ट्रिंग में push_back (0) भी कर सकते हैं और [0]
GaspardP

3

आप इसे इटरेटर का उपयोग करके बना सकते हैं।

std::string str = "string";
std::string::iterator p=str.begin();
char* chr = &(*p);

सौभाग्य।


3

Orlp के char का एक सुरक्षित संस्करण * unique_ptr का उपयोग करके उत्तर दें:

std::string str = "string";
auto cstr = std::make_unique<char[]>(str.length() + 1);
strcpy(cstr.get(), str.c_str());

3

उपयोग const char *से प्राप्त करने के लिए सदस्य फ़ंक्शन:std::stringc_str()

std::string str = "string";
const char* chr = str.c_str();

आप char *से एक नॉन-कास्ट प्राप्त करने के लिए सदस्य फ़ंक्शन का std::stringउपयोग कर सकते हैं data()जो C ++ 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()थी जब तक कि इसे बुलाया नहीं गया था।


2

यह भी चलेगा

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;  
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.