วิธีการแปลงสตริงเป็น char array ใน C ++


104

ผมอยากจะแปลงstringไปcharอาร์เรย์ char*แต่ไม่ ฉันรู้วิธีแปลงสตริงเป็นchar*(โดยใช้mallocหรือวิธีที่ฉันโพสต์ไว้ในโค้ดของฉัน) - แต่นั่นไม่ใช่สิ่งที่ฉันต้องการ ฉันแค่ต้องการแปลงstringเป็นchar[size]อาร์เรย์ เป็นไปได้ไหม?

#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
สิ่งนี้ดูเหมือนจะเป็น C ++ ไม่ใช่ C.
Fred Larson

@FredLarson: ตกลงแก้ไขขอบคุณ
Brian Brown

3
สามารถทำซ้ำได้ของstd :: string ถึง char *
cegprakash

คำตอบ:


126

วิธีที่ง่ายที่สุดที่ฉันคิดได้คือ:

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

เพื่อความปลอดภัยคุณอาจต้องการ:

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

หรืออาจเป็นแบบนี้:

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

9
สิ่งที่จับได้strncpyคือมันจะไม่ยุติเป็นโมฆะหากถึงขนาดก่อนที่จะพบค่าว่างในสตริงต้นทาง ก็ต้องระวังด้วย!
Fred Larson

1
ใช่ฉันคิดว่าเป็นวิธีที่สมเหตุสมผลในการจัดการ
Fred Larson

1
strncpy มีไว้เพื่อความปลอดภัยในนั้น strncpy จะไม่บุกรุกบัฟเฟอร์ที่คุณให้ไว้ strcpy_s ไม่ได้อยู่ใน C99 ด้วย แต่เพิ่งถูกเพิ่มใน C11
bames53

6
ฉันชอบวิธีที่ผู้คนใช้คำว่าความปลอดภัยในทางที่ผิด... โอ้มีที่ว่างไม่เพียงพอสำหรับสายดังนั้นขอตัดทอนออก .. โอ้เราเผลอลบข้อมูลเกี่ยวกับการแพ้ยาที่เป็นอันตรายถึงชีวิตของผู้ป่วยออกไป .. แต่เราไม่มี บัฟเฟอร์ล้นอีกต่อไป ฉันเดาว่าปลอดภัย ...
Karoly Horvath

4
@KarolyHorvath - ความปลอดภัยในโดเมนต่างๆ เห็นได้ชัดว่าคุณต้องตรวจสอบข้อกำหนดการใช้งานของคุณและอย่าทำสิ่งที่โง่เขลา แต่ถ้าคุณใช้บัฟเฟอร์มากเกินไปคุณจะสูญเสียการรับประกันว่าจะรู้ว่าจะเกิดอะไรขึ้น การเข้ารหัสที่ถูกต้องช่วยให้แน่ใจว่าโปรแกรม "ปลอดภัย" ที่จะทำงานบนระบบปฏิบัติการของคุณ การคิดที่ถูกต้องทำให้มั่นใจได้ว่าโปรแกรมจะ "ปลอดภัย" ในการทำสิ่งที่ผู้ใช้ต้องการ
Chowlett

58

โอเคฉันตกใจมากที่ไม่มีใครให้คำตอบที่ดีตอนนี้ถึงตาฉันแล้ว มีสองกรณี;

  1. อาร์เรย์คงถ่านเป็นที่ดีพอสำหรับคุณเพื่อให้คุณไปด้วย

    const char *array = tmp.c_str();
  2. หรือคุณต้องแก้ไขอาร์เรย์ถ่านดังนั้นค่าคงที่ไม่โอเคก็ไปด้วยสิ่งนี้

    char *array = &tmp[0];

ทั้งสองอย่างเป็นเพียงการดำเนินการมอบหมายและเวลาส่วนใหญ่เป็นเพียงสิ่งที่คุณต้องการหากคุณต้องการสำเนาใหม่จริงๆให้ทำตามคำตอบของเพื่อนคนอื่น ๆ


7
เขาต้องการอาร์เรย์ถ่านไม่ใช่ถ่าน *
harogaston

10
ตัวชี้ที่เขาสร้างขึ้นนั้นเหมือนกับอาร์เรย์ถ่าน ตัวแปรอาร์เรย์ใน C และ C ++ เป็นเพียงตัวชี้ไปยังองค์ประกอบแรกในอาร์เรย์
JustinCB

@ จัสติน ไม่จริง! ตัวแปรอาร์เรย์อาจสลายตัวเป็นพอยน์เตอร์ แต่ไม่เหมือนกันใน C ++ เช่นstd::size(elem)ใน C ++ มีการกำหนดไว้อย่างดีเมื่อelemเป็นchar arrayแต่ไม่สามารถรวบรวมได้เมื่อelemเป็นchar*หรือconst char*คุณสามารถดูได้ที่นี่
aniliitb10

17

วิธีที่ง่ายที่สุดก็คงเป็น

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

15
ขนาดอาร์เรย์ต้องเป็นค่าคงที่เวลาคอมไพล์ใน C ++
interjay

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 ใน C ++ ดังนั้นมาตรฐาน :: สตริง :: สำเนาควรจะเป็นทางเลือกแทนการstrcpy






2

หากคุณไม่ทราบขนาดของสตริงล่วงหน้าคุณสามารถจัดสรรอาร์เรย์แบบไดนามิก:

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

0

ฉันรู้ว่านี่อาจจะค่อนข้างโง่มากกว่าและเรียบง่าย แต่ฉันคิดว่ามันน่าจะใช้ได้:

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

ดีไม่จริง คุณเพียงแค่สมมติว่าไม่สามารถมีขนาดใหญ่กว่าn มันจะมีปัญหาหากb n>bดีกว่าที่จะใช้strcpyฟังก์ชันที่ให้มาแล้ว แก้ไข: ในบางกรณีอาจใช้งานได้ดียิ่งขึ้นstrcpy_sเนื่องจากเพิ่มการตรวจสอบตัวชี้ NULL (หากแพลตฟอร์มของคุณรองรับ)
droidballoon

0

หากคุณใช้ C ++ 11 ขึ้นไปฉันขอแนะนำให้ใช้std::snprintfมากกว่าstd::strcpyหรือstd::strncpyเนื่องจากความปลอดภัย (กล่าวคือคุณกำหนดจำนวนอักขระที่สามารถเขียนลงในบัฟเฟอร์ของคุณได้) และเนื่องจากมันสิ้นสุดค่าว่างสำหรับคุณ (ดังนั้น คุณไม่ต้องกังวลเกี่ยวกับเรื่องนี้) มันจะเป็นเช่นนี้:

#include <string>
#include <cstdio>

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

ใน C ++ 17 คุณมีทางเลือกนี้:

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

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, std::size(tab2), "%s", tmp.c_str());
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.