Làm thế nào để chuyển đổi chuỗi thành mảng char trong C ++?


103

Tôi muốn chuyển đổi stringsang charmảng nhưng không char*. Tôi biết cách chuyển đổi chuỗi thành char*(bằng cách sử dụng mallochoặc cách tôi đã đăng nó trong mã của mình) - nhưng đó không phải là điều tôi muốn. Tôi chỉ muốn chuyển đổi stringsang char[size]mảng. Nó có khả thi không?

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;

int main()
{
    // char to string
    char tab[4];
    tab[0] = 'c';
    tab[1] = 'a';
    tab[2] = 't';
    tab[3] = '\0';
    string tmp(tab);
    cout << tmp << "\n";

    // string to char* - but thats not what I want

    char *c = const_cast<char*>(tmp.c_str());
    cout << c << "\n";

    //string to char
    char tab2[1024];
    // ?

    return 0;
}

12
Xuất hiện này là C ++, không C.
Fred Larson

@FredLarson: ok, chỉnh sửa, nhờ
Brian Brown

3
có thể trùng lặp của std :: string để char *
cegprakash

Câu trả lời:


123

Cách đơn giản nhất mà tôi có thể nghĩ đến là:

string temp = "cat";
char tab2[1024];
strcpy(tab2, temp.c_str());

Để an toàn, bạn có thể thích:

string temp = "cat";
char tab2[1024];
strncpy(tab2, temp.c_str(), sizeof(tab2));
tab2[sizeof(tab2) - 1] = 0;

hoặc có thể theo kiểu này:

string temp = "cat";
char * tab2 = new char [temp.length()+1];
strcpy (tab2, temp.c_str());

9
Điểm bắt buộc strncpylà nó sẽ không kết thúc null nếu nó đạt đến kích thước trước khi nó tìm thấy null trong chuỗi nguồn. Tôi cũng phải cẩn thận với điều đó!
Fred Larson

1
Vâng, tôi nghĩ đó là một cách hợp lý để xử lý nó.
Fred Larson

1
strncpy là để an toàn trong đó strncpy sẽ không chạy quá bộ đệm mà bạn cung cấp cho nó. Ngoài ra strcpy_s không có trong C99, nhưng gần đây nó đã được thêm vào C11.
bames53

6
Tôi thích cách mọi người lạm dụng từ an toàn ... ồ, không có đủ chỗ cho chuỗi ký tự, vì vậy hãy cắt bớt nó đi .. ồ, chúng tôi đã vô tình xóa thông tin về bệnh dị ứng thuốc đe dọa tính mạng của bệnh nhân .. nhưng chúng tôi không có bộ đệm bị tràn nữa. tốt, tôi đoánan toàn ...
Karoly Horvath

4
@KarolyHorvath - an toàn trong các miền khác nhau. Rõ ràng, bạn cần kiểm tra các yêu cầu chức năng của mình và Không làm những điều ngu ngốc. Nhưng nếu bạn chạy quá mức bộ đệm, bạn sẽ mất bất kỳ đảm bảo nào về việc biết điều gì sẽ xảy ra. Mã hóa đúng đảm bảo chương trình "an toàn" để chạy trên hệ điều hành của bạn. Suy nghĩ chính xác đảm bảo chương trình "an toàn" khi làm những gì người dùng cần.
Chowlett

58

Ok, tôi bị sốc vì không có ai thực sự đưa ra câu trả lời xác đáng, giờ đến lượt tôi. Có hai trường hợp;

  1. Một mảng char không đổi đủ tốt cho bạn để bạn sử dụng,

    const char *array = tmp.c_str();
  2. Hoặc bạn cần sửa đổi mảng char nên hằng số không ổn, thì cứ làm như vậy

    char *array = &tmp[0];

Cả hai đều chỉ là hoạt động phân công và hầu hết thời gian đó chỉ là những gì bạn cần, nếu bạn thực sự cần một bản sao mới thì hãy làm theo các câu trả lời của nghiên cứu sinh khác.


7
Ông muốn có một mảng char, không phải là một char *
harogaston

10
Con trỏ mà anh ta tạo ra cũng giống như một mảng char. Một biến mảng trong C và C ++ chỉ là một con trỏ đến phần tử đầu tiên trong mảng.
JustinCB

@ JustinC.B. không hẳn! biến mảng có thể phân rã thành con trỏ nhưng chúng không giống nhau trong C ++. ví dụ như std::size(elem)trong C ++ cũng được định nghĩa khi elemlà một char arraynhưng nó thất bại trong việc biên dịch khi elemlà một char*hay const char*, bạn có thể nhìn thấy nó ở đây
aniliitb10

16

Cách dễ nhất để làm điều đó sẽ là

std::string myWord = "myWord";
char myArray[myWord.size()+1];//as 1 char space for null is also required
strcpy(myArray, myWord.c_str());

14
Kích thước mảng phải là một hằng số thời gian biên dịch trong C ++.
tục

12
str.copy(cstr, str.length()+1); // since C++11
cstr[str.copy(cstr, str.length())] = '\0';  // before C++11
cstr[str.copy(cstr, sizeof(cstr)-1)] = '\0';  // before C++11 (safe)

Cách tốt hơn là tránh C trong C ++, vì vậy std :: string :: copy nên là lựa chọn thay vì strcpy .



5

Hãy thử cách này nó sẽ hoạt động.

string line="hello world";
char * data = new char[line.size() + 1];
copy(line.begin(), line.end(), data);
data[line.size()] = '\0'; 


2

Bạn có thể sử dụng strcpy(), như vậy:

strcpy(tab2, tmp.c_str());

Coi chừng tràn bộ đệm.


2

Nếu bạn không biết trước kích thước của chuỗi, bạn có thể cấp phát động một mảng:

auto tab2 = std::make_unique<char[]>(temp.size() + 1);
std::strcpy(tab2.get(), temp.c_str());

0

Vâng, tôi biết điều này có lẽ khá ngớ ngẩn hơn và đơn giản, nhưng tôi nghĩ rằng nó sẽ làm việc:

string n;
cin>> n;
char b[200];
for (int i = 0; i < sizeof(n); i++)
{
    b[i] = n[i];
    cout<< b[i]<< " ";
}

Chà, không hẳn. Bạn chỉ giả định rằng nkhông thể lớn hơn b. Nó sẽ sụp đổ nếu n>b. Tốt hơn nên sử dụng strcpychức năng đã được cung cấp. Chỉnh sửa: Tại một số trường hợp nó có thể là tốt hơn để sử dụng strcpy_svì nó cho biết thêm kiểm tra cho con trỏ NULL (nếu hỗ trợ nền tảng của bạn nó)
droidballoon

0

Nếu bạn đang sử dụng C ++ 11 trở lên, tôi khuyên bạn nên sử dụng std::snprintfhơn std::strcpyhoặc std::strncpyvì tính an toàn của nó (tức là bạn xác định có bao nhiêu ký tự có thể được ghi vào bộ đệm của mình) và vì nó null-chấm dứt chuỗi cho bạn (vì vậy bạn không phải lo lắng về nó). Nó sẽ như thế này:

#include <string>
#include <cstdio>

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, sizeof(tab2), "%s", tmp.c_str());

Trong C ++ 17, bạn có thay thế này:

#include <string>
#include <cstdio>
#include <iterator>

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, std::size(tab2), "%s", tmp.c_str());
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.