C ++ 'da dizeyi char dizisine dönüştürme nasıl yapılır?


104

Ben dönüştürmek istiyorum stringiçin chardizinin ancak char*. Dizeyi char*(kullanarak mallocveya kodumda yayınladığım şekilde) nasıl dönüştüreceğimi biliyorum - ama istediğim bu değil. Ben sadece dönüştürmek istediğiniz stringiçin char[size]diziden. Mümkün mü?

#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
Bu, C değil, C ++ gibi görünüyor
Fred Larson

@FredLarson: Tamam, düzenlendi, teşekkürler
Brian Brown

Yanıtlar:


126

Bunu yapmanın en basit yolu şudur:

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

Güvenlik için şunları tercih edebilirsiniz:

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

veya şu şekilde olabilir:

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

9
İle yakalamak strncpy, kaynak dizede bir null bulmadan önce boyuta ulaşırsa boş sonlanmayacağıdır. Buna da dikkat etmelisin!
Fred Larson

1
Evet, bunun üstesinden gelmenin makul bir yolu olduğunu düşünüyorum.
Fred Larson

1
strncpy güvenlik içindir, çünkü strncpy, verdiğiniz arabelleği aşmayacaktır. Ayrıca strcpy_s C99'da değildir, ancak yakın zamanda C11'e eklenmiştir.
bames53

6
İnsanların güvenlik kelimesini kötüye kullanma şeklini seviyorum ... oh, ip için yeterli yer yok, o yüzden keselim .. oh, hastanın hayatını tehdit eden ilaç alerjisi hakkındaki bilgileri yanlışlıkla sildik .. ama bizde yok artık bir arabellek taşması. peki, sanırım öyle güvenli ...
Karoly Horvath

4
@KarolyHorvath - farklı alanlarda güvenlik. Açıkçası, işlevsel gereksinimlerinizi kontrol etmeniz ve Aptalca Şeyler Yapmamalısınız. Ancak tamponu aşarsanız, ne olacağını bilme garantinizi kaybedersiniz. Doğru kodlama, programın işletim sisteminizde çalışması için "güvenli" olmasını sağlar. Doğru düşünme , programın kullanıcının ihtiyaç duyduğu şeyi yapmada "güvenli" olmasını sağlar.
Chowlett

58

Tamam, kimsenin gerçekten iyi bir cevap vermemesine şok oldum, şimdi sıra bende. İki durum var;

  1. Bir sabit karakter dizisi ile gitmek yüzden, sizin için iyi yeterlidir

    const char *array = tmp.c_str();
  2. Veya char dizisini değiştirmeniz gerekir, böylece sabit tamam olmaz, o zaman bununla devam edin

    char *array = &tmp[0];

Her ikisi de sadece atama işlemleri ve çoğu zaman tam da ihtiyacınız olan şey bu, gerçekten yeni bir kopyaya ihtiyacınız varsa diğer arkadaşların cevaplarını takip edin.


7
Bir karakter dizisi istiyor, karakter değil *
harogaston

10
Oluşturduğu işaretçi, bir karakter dizisi ile aynı şey. C ve C ++ 'daki bir dizi değişkeni, dizideki ilk öğeye yalnızca bir göstericidir.
JustinCB

@ JustinC.B. pek sayılmaz! Dizi değişkenleri çürümeye olabilir işaretçiler içine ancak C ++ aynı değildir. örneğin std::size(elem)C ++ 'da ne zaman elema olduğu iyi tanımlanır, char arrayancak ne zaman elema char*veya olduğunda derleme başarısız olur const char*, burada
aniliitb10

17

Bunu yapmanın en kolay yolu bu olurdu

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

15
Dizi boyutu, C ++ 'da bir derleme zamanı sabiti olmalıdır.
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 ++ 'da C'den kaçınmak daha iyi bir uygulamadır, bu nedenle strcpy yerine std :: string :: copy tercih edilmelidir .



5

Bu şekilde deneyin, işe yaramalı.

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


2

Şöyle kullanabilirsiniz strcpy():

strcpy(tab2, tmp.c_str());

Arabellek taşmasına dikkat edin.


2

Dizenin boyutunu önceden bilmiyorsanız, dinamik olarak bir dizi tahsis edebilirsiniz:

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

0

Eh bu belki daha ziyade aptal biliyorum daha basit, ama çalışması gerekir düşünüyorum:

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

Aslında değil. Sadece nbundan daha büyük olamayacağını varsayıyorsun b. Olursa çöker n>b. strcpyZaten sağlanan işlevi kullanmak daha iyidir. Düzenleme: Bazı durumlarda strcpy_s, NULL işaretçiler için kontrol eklediği için kullanmak daha da iyi olabilir (platformunuz destekliyorsa)
droidballoon

0

C ++ 11 veya üstünü kullanıyorsanız , güvenliğinden veya std::snprintfüstünden kullanmanızı öneririm (yani, arabelleğinize kaç karakter yazılabileceğini belirlersiniz) ve sizin için dizeyi boş olarak sonlandırdığı için (yani bunun için endişelenmenize gerek yok). Şöyle olurdu:std::strcpystd::strncpy

#include <string>
#include <cstdio>

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

C ++ 17'de şu alternatife sahipsiniz:

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

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, std::size(tab2), "%s", tmp.c_str());
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.