Làm cách nào để chuyển đổi một chuỗi std :: thành const char * hoặc char *?


894

Làm thế nào tôi có thể chuyển đổi std::stringmột char*hoặc một const char*?


2
Thay vì: char * writable = new char [str.size () + 1]; Bạn có thể sử dụng char writable [str.size () + 1]; Sau đó, bạn không cần phải lo lắng về việc xóa xử lý có thể ghi hoặc ngoại lệ.

7
Bạn không thể sử dụng str.size () trừ khi kích thước được biết tại thời gian biên dịch, nó cũng có thể tràn qua ngăn xếp của bạn nếu giá trị kích thước cố định là rất lớn.
paulm

1
char * result = strcpy ((char *) malloc (str.length () + 1), str.c_str ());
cegprakash

7
@cegprakash strcpymallockhông thực sự là cách của C ++.
boycy

4
Không, nhưng char* dest = new char[str.length() + 1]; std::copy(str.begin(), str.end(), dest)sẽ là C ++ thành ngữ hơn. strcpy()malloc()không sai hoặc có vấn đề, nhưng dường như không nhất quán khi sử dụng chuỗi C ++ và các tiện ích thư viện C có tương đương C ++ trong cùng một khối mã.
boycy

Câu trả lời:


1056

Nếu bạn chỉ muốn truyền std::stringmột hàm cho nhu cầu, const char*bạn có thể sử dụng

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

Nếu bạn muốn có được một bản sao có thể ghi, như char *, bạn có thể làm điều đó với điều này:

std::string str;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0

// don't forget to free the string after finished using it
delete[] writable;

Chỉnh sửa : Lưu ý rằng ở trên không phải là ngoại lệ an toàn. Nếu bất cứ điều gì giữa newcuộc gọi và deletecuộc gọi ném, bạn sẽ bị rò rỉ bộ nhớ, vì không có gì sẽ deletetự động gọi cho bạn. Có hai cách ngay lập tức để giải quyết điều này.

boost :: scoped_array

boost::scoped_array sẽ xóa bộ nhớ cho bạn khi đi ra khỏi phạm vi:

std::string str;
boost::scoped_array<char> writable(new char[str.size() + 1]);
std::copy(str.begin(), str.end(), writable.get());
writable[str.size()] = '\0'; // don't forget the terminating 0

// get the char* using writable.get()

// memory is automatically freed if the smart pointer goes 
// out of scope

std :: vector

Đây là cách tiêu chuẩn (không yêu cầu bất kỳ thư viện bên ngoài). Bạn sử dụng std::vector, mà hoàn toàn quản lý bộ nhớ cho bạn.

std::string str;
std::vector<char> writable(str.begin(), str.end());
writable.push_back('\0');

// get the char* using &writable[0] or &*writable.begin()

41
Chỉ cần sử dụng char * result = strdup (str.c_str ());
Jasper Bekkers

63
bạn có thể, nhưng strdup không phải là chức năng tiêu chuẩn ac hoặc c ++, đó là từ posix :)
Johannes Schaub - litb

14
những gì tôi có thể thích nói chung là std :: vector <char> writable (str.begin (), str.end ()); writable.push_back ('\ 0'); char * c = & có thể ghi [0];
Julian Schaub - litb

17
std :: copy là cách c ++ để thực hiện việc này mà không cần lấy con trỏ chuỗi. Tôi cố gắng tránh sử dụng các chức năng C nhiều nhất có thể.
Julian Schaub - litb

16
Kể từ C ++ 17, std::string::data()bây giờ trả về a CharT*thay vì a const CharT*. Có thể là một ý tưởng tốt để cập nhật câu trả lời này :)
Rakete1111

192

Đã nói ...

std::string x = "hello";

Lấy một `char *` hoặc `const char *` từ một chuỗi`

Làm cách nào để có được một con trỏ ký tự hợp lệ trong khi xvẫn ở trong phạm vi và không được sửa đổi thêm

C ++ 11 đơn giản hóa mọi thứ; tất cả những điều sau đây cung cấp quyền truy cập vào cùng bộ đệm chuỗi bên trong:

const char* p_c_str = x.c_str();
const char* p_data  = x.data();
char* p_writable_data = x.data(); // for non-const x from C++17 
const char* p_x0    = &x[0];

      char* p_x0_rw = &x[0];  // compiles iff x is not const...

Tất cả các con trỏ trên sẽ giữ cùng một giá trị - địa chỉ của ký tự đầu tiên trong bộ đệm. Ngay cả một chuỗi rỗng cũng có "ký tự đầu tiên trong bộ đệm", bởi vì C ++ 11 đảm bảo luôn giữ thêm một ký tự kết thúc NUL / 0 sau khi nội dung chuỗi được gán rõ ràng (ví dụ: std::string("this\0that", 9)sẽ có bộ đệm "this\0that\0").

Cho bất kỳ con trỏ trên:

char c = p[n];   // valid for n <= x.size()
                 // i.e. you can safely read the NUL at p[x.size()]

Chỉ dành cho constcon trỏ p_writable_datavà từ &x[0]:

p_writable_data[n] = c;
p_x0_rw[n] = c;  // valid for n <= x.size() - 1
                 // i.e. don't overwrite the implementation maintained NUL

Viết một NUL ở nơi khác trong chuỗi không thay đổi string's size(); stringChúng được phép chứa bất kỳ số lượng NUL nào - chúng không được xử lý đặc biệt bằng std::string(tương tự trong C ++ 03).

Trong C ++ 03 , mọi thứ phức tạp hơn đáng kể (các khác biệt chính được tô sáng ):

  • x.data()

    • trả về const char*bộ đệm bên trong của chuỗi mà Tiêu chuẩn không yêu cầu để kết luận với NUL (nghĩa là có thể được ['h', 'e', 'l', 'l', 'o']theo sau bởi các giá trị rác chưa được xác định hoặc với các truy cập ngẫu nhiên có hành vi không xác định ).
      • x.size()ký tự được an toàn để đọc, tức là x[0]thông quax[x.size() - 1]
      • đối với các chuỗi trống, bạn được đảm bảo một số con trỏ không phải là NULL mà 0 có thể được thêm một cách an toàn (Hurrah!), nhưng bạn không nên bỏ qua con trỏ đó.
  • &x[0]

    • đối với các chuỗi rỗng, hành vi này không xác định (21.3.4)
      • ví dụ như f(const char* p, size_t n) { if (n == 0) return; ...whatever... }bạn không được gọi f(&x[0], x.size());khi x.empty()- chỉ cần sử dụng f(x.data(), ...).
    • mặt khác, theo x.data()nhưng:
      • đối với phi const xnày sẽ mang lại một const char*con trỏ không ; bạn có thể ghi đè nội dung chuỗi
  • x.c_str()

    • trả về const char*giá trị đại diện ASCIIZ (chấm dứt NUL) của giá trị (nghĩa là ['h', 'e', ​​'l', 'l', 'o', '\ 0']).
    • mặc dù vài nếu có triển khai đã chọn để làm như vậy, C ++ 03 chuẩn bị diễn đạt để cho phép việc thực hiện chuỗi sự tự do để tạo ra một bộ đệm NUL-chấm dứt phân biệt một cách nhanh chóng , từ khả năng phi NUL chấm dứt đệm "tiếp xúc" bởi x.data()&x[0]
    • x.size() + 1 ký tự an toàn để đọc.
    • được đảm bảo an toàn ngay cả đối với các chuỗi trống (['\ 0']).

Hậu quả của việc truy cập các chỉ số pháp lý bên ngoài

Dù bạn có con trỏ bằng cách nào, bạn cũng không được truy cập bộ nhớ dọc theo con trỏ so với các ký tự được đảm bảo có trong các mô tả ở trên. Những nỗ lực để làm như vậy có hành vi không xác định , với khả năng rất cao là sự cố ứng dụng và kết quả rác ngay cả khi đọc và thêm dữ liệu bán buôn, ngăn chặn tham nhũng và / hoặc lỗ hổng bảo mật để ghi.

Khi nào những con trỏ bị vô hiệu?

Nếu bạn gọi một số stringhàm thành viên sửa đổi stringhoặc dự trữ dung lượng thêm, mọi giá trị con trỏ được trả về trước bởi bất kỳ phương thức nào ở trên đều bị vô hiệu . Bạn có thể sử dụng các phương thức đó một lần nữa để có được một con trỏ khác. (Các quy tắc tương tự như đối với các trình vòng lặp thành strings).

Xem thêm Làm thế nào để có được một con trỏ ký tự hợp lệ ngay cả sau khi xphạm vi lá hoặc được sửa đổi thêm bên dưới ....

Vì vậy, cái nào tốt hơn để sử dụng?

Từ C ++ 11, sử dụng .c_str()cho dữ liệu ASCIIZ và .data()cho dữ liệu "nhị phân" (giải thích thêm bên dưới).

Trong C ++ 03, sử dụng .c_str()trừ khi chắc chắn .data()là đủ và thích hợp .data()hơn &x[0]vì nó an toàn cho các chuỗi trống ....

... Cố gắng hiểu chương trình đủ để sử dụng data()khi thích hợp, hoặc có thể bạn sẽ mắc các lỗi khác ...

Ký tự ASCII NUL '\ 0' được đảm bảo bởi .c_str()nhiều chức năng được sử dụng làm giá trị trọng tâm biểu thị sự kết thúc của dữ liệu có liên quan và an toàn khi truy cập. Điều này áp dụng cho cả C ++ - chỉ các chức năng như nói fstream::fstream(const char* filename, ...)và chia sẻ với các chức năng như strchr(), và printf().

Với sự .c_str()đảm bảo của C ++ 03 về bộ đệm được trả về là một bộ siêu tập hợp .data(), bạn luôn có thể sử dụng một cách an toàn .c_str(), nhưng đôi khi mọi người không vì:

  • sử dụng .data()giao tiếp với các lập trình viên khác đang đọc mã nguồn rằng dữ liệu không phải là ASCIIZ (thay vào đó, bạn đang sử dụng chuỗi để lưu trữ một khối dữ liệu (đôi khi thậm chí không thực sự bằng văn bản)) hoặc bạn đang truyền nó tới một chức năng khác coi nó như một khối dữ liệu "nhị phân". Đây có thể là một cái nhìn sâu sắc quan trọng trong việc đảm bảo rằng các thay đổi mã của các lập trình viên khác tiếp tục xử lý dữ liệu đúng cách.
  • Chỉ C ++ 03: có một cơ hội nhỏ rằng stringviệc triển khai của bạn sẽ cần thực hiện một số cấp phát bộ nhớ bổ sung và / hoặc sao chép dữ liệu để chuẩn bị bộ đệm kết thúc NUL

Một gợi ý nữa, nếu các tham số của hàm yêu cầu ( const) char*nhưng không khăng khăng nhận x.size(), thì hàm đó có thể cần đầu vào ASCIIZ, vì vậy, đó .c_str()là một lựa chọn tốt (hàm cần biết văn bản kết thúc bằng cách nào đó, vì vậy nếu không một tham số riêng biệt, nó chỉ có thể là một quy ước như tiền tố độ dài hoặc sentinel hoặc một số độ dài dự kiến ​​cố định).

Làm thế nào để có được một con trỏ ký tự hợp lệ ngay cả sau khi xrời khỏi phạm vi hoặc được sửa đổi thêm

Bạn sẽ cần sao chép nội dung của vùng string xnhớ mới bên ngoài x. Bộ đệm ngoài này có thể ở nhiều nơi như một stringbiến mảng hoặc ký tự khác, nó có thể có hoặc không có thời gian tồn tại khác với xdo ở một phạm vi khác (ví dụ: không gian tên, toàn cầu, tĩnh, heap, bộ nhớ chia sẻ, tệp ánh xạ bộ nhớ) .

Để sao chép văn bản từ std::string xthành một mảng ký tự độc lập:

// USING ANOTHER STRING - AUTO MEMORY MANAGEMENT, EXCEPTION SAFE
std::string old_x = x;
// - old_x will not be affected by subsequent modifications to x...
// - you can use `&old_x[0]` to get a writable char* to old_x's textual content
// - you can use resize() to reduce/expand the string
//   - resizing isn't possible from within a function passed only the char* address

std::string old_x = x.c_str(); // old_x will terminate early if x embeds NUL
// Copies ASCIIZ data but could be less efficient as it needs to scan memory to
// find the NUL terminator indicating string length before allocating that amount
// of memory to copy into, or more efficient if it ends up allocating/copying a
// lot less content.
// Example, x == "ab\0cd" -> old_x == "ab".

// USING A VECTOR OF CHAR - AUTO, EXCEPTION SAFE, HINTS AT BINARY CONTENT, GUARANTEED CONTIGUOUS EVEN IN C++03
std::vector<char> old_x(x.data(), x.data() + x.size());       // without the NUL
std::vector<char> old_x(x.c_str(), x.c_str() + x.size() + 1);  // with the NUL

// USING STACK WHERE MAXIMUM SIZE OF x IS KNOWN TO BE COMPILE-TIME CONSTANT "N"
// (a bit dangerous, as "known" things are sometimes wrong and often become wrong)
char y[N + 1];
strcpy(y, x.c_str());

// USING STACK WHERE UNEXPECTEDLY LONG x IS TRUNCATED (e.g. Hello\0->Hel\0)
char y[N + 1];
strncpy(y, x.c_str(), N);  // copy at most N, zero-padding if shorter
y[N] = '\0';               // ensure NUL terminated

// USING THE STACK TO HANDLE x OF UNKNOWN (BUT SANE) LENGTH
char* y = alloca(x.size() + 1);
strcpy(y, x.c_str());

// USING THE STACK TO HANDLE x OF UNKNOWN LENGTH (NON-STANDARD GCC EXTENSION)
char y[x.size() + 1];
strcpy(y, x.c_str());

// USING new/delete HEAP MEMORY, MANUAL DEALLOC, NO INHERENT EXCEPTION SAFETY
char* y = new char[x.size() + 1];
strcpy(y, x.c_str());
//     or as a one-liner: char* y = strcpy(new char[x.size() + 1], x.c_str());
// use y...
delete[] y; // make sure no break, return, throw or branching bypasses this

// USING new/delete HEAP MEMORY, SMART POINTER DEALLOCATION, EXCEPTION SAFE
// see boost shared_array usage in Johannes Schaub's answer

// USING malloc/free HEAP MEMORY, MANUAL DEALLOC, NO INHERENT EXCEPTION SAFETY
char* y = strdup(x.c_str());
// use y...
free(y);

Các lý do khác để muốn một char*hoặc const char*được tạo ra từ mộtstring

Vì vậy, ở trên bạn đã thấy làm thế nào để có một ( const) char*và làm thế nào để tạo một bản sao của văn bản độc lập với bản gốc string, nhưng bạn có thể làm gì với nó? Một sự phá vỡ ngẫu nhiên của các ví dụ ...

  • cấp quyền truy cập mã "C" cho stringvăn bản của C ++ , như trongprintf("x is '%s'", x.c_str());
  • sao chép xvăn bản vào bộ đệm được chỉ định bởi người gọi chức năng của bạn (ví dụ strncpy(callers_buffer, callers_buffer_size, x.c_str())) hoặc bộ nhớ dễ bay hơi được sử dụng cho I / O của thiết bị (ví dụ for (const char* p = x.c_str(); *p; ++p) *p_device = *p;)
  • nối xvăn bản của bạn vào một mảng ký tự đã chứa một số văn bản ASCIIZ (ví dụ strcat(other_buffer, x.c_str())) - hãy cẩn thận để không tràn bộ đệm (trong nhiều tình huống bạn có thể cần sử dụng strncat)
  • trả về một const char*hoặc char*từ một chức năng (có thể vì lý do lịch sử - khách hàng đang sử dụng API hiện tại của bạn - hoặc để tương thích với C mà bạn không muốn trả lại std::string, nhưng muốn sao chép stringdữ liệu của bạn ở đâu đó cho người gọi)
    • cẩn thận không trả về một con trỏ có thể bị hủy bởi người gọi sau khi một stringbiến cục bộ mà con trỏ trỏ trỏ có phạm vi rời
    • một số dự án với các đối tượng được chia sẻ được biên dịch / liên kết cho các std::stringtriển khai khác nhau (ví dụ STLport và trình biên dịch gốc) có thể truyền dữ liệu dưới dạng ASCIIZ để tránh xung đột

4
Đẹp một. Một lý do khác để muốn một char * (non const) là hoạt động với phát sóng MPI. Nó trông đẹp hơn nếu bạn không phải sao chép qua lại. Cá nhân tôi đã cung cấp một char * const getter cho chuỗi. Con trỏ Const, nhưng chuỗi có thể chỉnh sửa. Mặc dù nó có thể đã bị rối với việc chuyển đổi ngầm định từ const char * sang chuỗi ...
bartgol

33

Sử dụng .c_str()phương pháp cho const char *.

Bạn có thể sử dụng &mystring[0]để lấy một char *con trỏ, nhưng có một vài điều của gotcha: bạn không nhất thiết phải có một chuỗi kết thúc bằng 0 và bạn sẽ không thể thay đổi kích thước của chuỗi. Bạn đặc biệt phải cẩn thận không thêm các ký tự qua cuối chuỗi hoặc bạn sẽ bị tràn bộ đệm (và có thể xảy ra sự cố).

Không có gì đảm bảo rằng tất cả các nhân vật sẽ là một phần của bộ đệm liền kề cho đến C ++ 11, nhưng trong thực tế, tất cả các triển khai đã biết đều std::stringhoạt động theo cách đó; xem Có phải & & [0] Chỉ điểm cho các ký tự tiếp giáp trong chuỗi std :: không? .

Lưu ý rằng nhiều stringhàm thành viên sẽ phân bổ lại bộ đệm nội bộ và làm mất hiệu lực mọi con trỏ bạn có thể đã lưu. Tốt nhất để sử dụng chúng ngay lập tức và sau đó loại bỏ.


1
bạn nên lưu ý rằng dữ liệu () trả về const char * :) ý của bạn là & str [0], trả về một chuỗi kết thúc null không liên tục, nhưng không cần thiết.
Julian Schaub - litb

1
@lít, Argh! Đó là những gì tôi nhận được khi cố gắng đưa ra câu trả lời nhanh chóng. Tôi đã sử dụng giải pháp của bạn trong quá khứ, không biết tại sao đó không phải là điều đầu tiên xuất hiện trong tâm trí. Tôi đã chỉnh sửa câu trả lời của mình.
Đánh dấu tiền chuộc

2
Về mặt kỹ thuật, lưu trữ chuỗi std :: sẽ chỉ tiếp giáp trong C ++ 0x.
MSalters

1
@MSalters, cảm ơn - Tôi không biết điều đó. Tuy nhiên, tôi rất khó tìm được một triển khai trong trường hợp không phải như vậy.
Đánh dấu tiền chuộc

2
char * result = strcpy (malloc (str.length () + 1), str.c_str ());
cegprakash

21

C ++ 17

C ++ 17 (tiêu chuẩn sắp tới) thay đổi tóm tắt của mẫu basic_stringthêm quá tải không const data():

charT* data() noexcept;

Trả về: Một con trỏ p sao cho p + i == & toán tử cho mỗi i trong [0, size ()].


CharT const * từ std::basic_string<CharT>

std::string const cstr = { "..." };
char const * p = cstr.data(); // or .c_str()

CharT * từ std::basic_string<CharT>

std::string str = { "..." };
char * p = str.data();

C ++ 11

CharT const * từ std::basic_string<CharT>

std::string str = { "..." };
str.c_str();

CharT * từ std::basic_string<CharT>

Từ C ++ 11 trở đi, tiêu chuẩn cho biết:

  1. Các đối tượng giống như char trong một basic_stringđối tượng sẽ được lưu trữ liên tục. Đó là, đối với bất kỳ basic_stringđối tượng nào s, danh tính &*(s.begin() + n) == &*s.begin() + nsẽ giữ cho tất cả các giá trị nđó 0 <= n < s.size().

  1. const_reference operator[](size_type pos) const;
    reference operator[](size_type pos);

    Trả về: *(begin() + pos)if pos < size(), nếu không, tham chiếu đến một đối tượng có loại CharTcó giá trị CharT(); giá trị tham chiếu sẽ không được sửa đổi.


  1. const charT* c_str() const noexcept;
    const charT* data() const noexcept;

    Trả về: Một con trỏ p sao p + i == &operator[](i)cho mỗi itrong [0,size()].

Có nhiều cách có thể để có được một con trỏ ký tự không const.

1. Sử dụng bộ lưu trữ liền kề của C ++ 11

std::string foo{"text"};
auto p = &*foo.begin();

Chuyên nghiệp

  • Đơn giản và ngắn gọn
  • Nhanh (chỉ có phương pháp không có bản sao liên quan)

Nhược điểm

  • Cuối cùng '\0'là không được thay đổi / không nhất thiết phải là một phần của bộ nhớ không const.

2. Sử dụng std::vector<CharT>

std::string foo{"text"};
std::vector<char> fcv(foo.data(), foo.data()+foo.size()+1u);
auto p = fcv.data();

Chuyên nghiệp

  • Đơn giản
  • Xử lý bộ nhớ tự động
  • Năng động

Nhược điểm

  • Yêu cầu sao chép chuỗi

3. Sử dụng std::array<CharT, N>if Nlà biên dịch thời gian không đổi (và đủ nhỏ)

std::string foo{"text"};
std::array<char, 5u> fca;
std::copy(foo.data(), foo.data()+foo.size()+1u, fca.begin());

Chuyên nghiệp

  • Đơn giản
  • Xử lý bộ nhớ ngăn xếp

Nhược điểm

  • Tĩnh
  • Yêu cầu sao chép chuỗi

4. Cấp phát bộ nhớ thô với xóa bộ nhớ tự động

std::string foo{ "text" };
auto p = std::make_unique<char[]>(foo.size()+1u);
std::copy(foo.data(), foo.data() + foo.size() + 1u, &p[0]);

Chuyên nghiệp

  • Dấu chân bộ nhớ nhỏ
  • Xóa tự động
  • Đơn giản

Nhược điểm

  • Yêu cầu sao chép chuỗi
  • Tĩnh (sử dụng động đòi hỏi nhiều mã hơn)
  • Ít tính năng hơn vector hoặc mảng

5. Cấp phát bộ nhớ thô với xử lý thủ công

std::string foo{ "text" };
char * p = nullptr;
try
{
  p = new char[foo.size() + 1u];
  std::copy(foo.data(), foo.data() + foo.size() + 1u, p);
  // handle stuff with p
  delete[] p;
}
catch (...)
{
  if (p) { delete[] p; }
  throw;
}

Chuyên nghiệp

  • 'Kiểm soát' tối đa

Con

  • Yêu cầu sao chép chuỗi
  • Trách nhiệm tối đa / dễ bị lỗi
  • Phức tạp

9

Tôi đang làm việc với một API với rất nhiều chức năng nhận làm đầu vào a char*.

Tôi đã tạo ra một lớp nhỏ để đối mặt với loại vấn đề này, tôi đã thực hiện thành ngữ RAII.

class DeepString
{
        DeepString(const DeepString& other);
        DeepString& operator=(const DeepString& other);
        char* internal_; 

    public:
        explicit DeepString( const string& toCopy): 
            internal_(new char[toCopy.size()+1]) 
        {
            strcpy(internal_,toCopy.c_str());
        }
        ~DeepString() { delete[] internal_; }
        char* str() const { return internal_; }
        const char* c_str()  const { return internal_; }
};

Và bạn có thể sử dụng nó như:

void aFunctionAPI(char* input);

//  other stuff

aFunctionAPI("Foo"); //this call is not safe. if the function modified the 
                     //literal string the program will crash
std::string myFoo("Foo");
aFunctionAPI(myFoo.c_str()); //this is not compiling
aFunctionAPI(const_cast<char*>(myFoo.c_str())); //this is not safe std::string 
                                                //implement reference counting and 
                                                //it may change the value of other
                                                //strings as well.
DeepString myDeepFoo(myFoo);
aFunctionAPI(myFoo.str()); //this is fine

Tôi đã gọi lớp DeepStringvì nó đang tạo một bản sao sâu và duy nhất ( DeepStringkhông thể sao chép ) của một chuỗi hiện có.


3
Tôi sẽ tránh quy ước đặt tên này. c_str()như được sử dụng bởi stdlà viết tắt của "C-string" chứ không phải "const string" và str()luôn trả về a std::basic_string, không char*(ví dụ std::stringstream::str())
bcrist

8
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());

1
Trông lạ mắt nhưng thực sự khó hiểu ... Đơn giản là IMO tốt nhất
Naeem A. Malik

4
strcpy (), malloc (), length () và c_str () là các hàm cơ bản và không có gì khó trong việc này. Chỉ cần phân bổ bộ nhớ và sao chép.
cegprakash

5
vâng, các chức năng là cơ bản nhưng bạn đã vặn và uốn cong chúng trông giống như bát mì spaghetti hoặc một con quái vật của Frankenstein :)
Naeem A. Malik

4
Vâng, các chức năng là cơ bản nhưng ... bạn có nhớ khi bạn bắt đầu làm việc với ngôn ngữ lập trình không? Một số dòng nhiều hơn để giải thích và nó thực sự sẽ giúp một người mới tìm hiểu lý do tại sao ví dụ khác hoặc tốt hơn câu trả lời này :)
Hastur

2
@cegprakash: Bất cứ khi nào có malloc (), cũng phải có một () miễn phí. Mặt khác, mã bị rò rỉ bộ nhớ và giải pháp trong câu trả lời của bạn cũng vậy. Phân bổ bộ nhớ mà không ít nhất là gợi ý cho sự giải quyết cần thiết là thực tiễn tồi cho những câu hỏi như vậy.
Striezel

7

Chỉ cần nhìn thấy điều này:

string str1("stackoverflow");
const char * str2 = str1.c_str();

Tuy nhiên, lưu ý rằng điều này sẽ trở lại a const char *.

Đối với a char *, sử dụng strcpyđể sao chép nó vào một charmảng khác .


23
Xin chào, những gì bạn đã đăng đã được nói nhiều lần, với nhiều chi tiết hơn, trong các câu trả lời khác cho câu hỏi 5 tuổi. Sẽ tốt hơn nếu trả lời các câu hỏi cũ hơn, nhưng chỉ khi bạn thêm thông tin mới. Nếu không, đó chỉ là tiếng ồn.
Mat

7
Cá nhân, tôi đánh giá cao sự đơn giản.
TankorSmash

-4

Thử cái này

std::string s(reinterpret_cast<const char *>(Data), Size);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.