char * dönüştürmek std :: string


262

Ben std::stringtarafından alınan veri depolamak için bir kullanmanız gerekir fgets(). Dönüştürmek için bu ben gereğini yapmak için char*dönüş değeri fgets()bir içine std::stringbir dizide mağazaya. Bu nasıl yapılabilir?

Yanıtlar:


376

std::string bunun için bir kurucu var:

const char *s = "Hello, World!";
std::string str(s);

Bu yapı, adres listesindeki karakter listesini derin kopyalar sve solmamalıdır nullptrya da başka bir davranışın tanımsız olduğunu unutmayın.


6
öyleyse ne olacak?
Carson Myers

14
Standard, yapıcı parametresinin "boş gösterici olmayacağını" söylüyor - herhangi bir istisna atılmadığını belirtmiyor.

24
Sığ veya derin kopya mı?

4
@pushkin No strsadece değişken bir isimdir. Bu şey olabilir: S, abc, l, I, strHelloWorld. Açıkçası bazı seçimler diğerlerinden daha iyidir. Ancak bu örnek striçin oldukça kabul edilebilir.
Hayal kırıklığına uğramış

10
@Madhatter derin bir kopya. İşaretçi ayırma kalır ve dize kendisini yeni bir ayırma yapar.
moodboom

127

Karakter * boyutunu zaten biliyorsanız, bunun yerine bunu kullanın

char* data = ...;
int size = ...;
std::string myString(data, size);

Bu strlen kullanmaz.

EDIT: Dize değişkeni zaten varsa, ata () kullanın:

std::string myString;
char* data = ...;
int size = ...;
myString.assign(data, size);

1
Bir tür yan soru Eugene. Eğer veriler daha sonra rutinde kadar doldurulur değil, nasıl o zaman MyString initialize musunuz? MyString değişkenini doldurulduğunda bildirir misiniz?
IcedDante

2
int size = strlen (veri);
Vlad

@vlad: fikir, başka bir kaynaktan ve / veya verilerin boyutunun bir C-dizesi olmadığını bilmenizdir (null'leri katıştırır veya null ile bitmez). Bir C-dizeniz varsa myString = data; sizin için strlen veya eşdeğeri çalışacaktır.
Eugene

1
@huseyintugrulbuyukisik Hala orijinal belleği düzgün bir şekilde atmanız gerekir - std :: string baytları kopyalar, sahiplik almaz.
Eugene

2
@ZackLee, baytlar için yeni bir bellek ayıracak ve hepsini oraya kopyalayacaktır. Sığ kopya için potansiyel istiyorsanız, bir std :: dizesini diğerine kopyalamanız gerekir. O zaman bazı uygulamalar sığ bir kopya yapabilir diye düşünüyorum.
Eugene

31

Çoğu cevap inşa hakkında konuşuyor std::string.

Önceden oluşturulmuşsa, yalnızca atama işlecini kullanın .

std::string oString;
char* pStr;

... // Here allocate and get character string (e.g. using fgets as you mentioned)

oString = pStr; // This is it! It copies contents from pStr to oString

28

Ben fgets () tarafından alınan veri depolamak için std :: string kullanmanız gerekir.

fgets()C ++ programlarken neden kullanıyorsunuz ? Neden olmasın std::getline()?


18

Yapıcıdan geçirin:

const char* dat = "my string!";
std::string my_string( dat );

Diğer yöne gitmek için string.c_str () işlevini kullanabilirsiniz:

std::string my_string("testing!");
const char* dat = my_string.c_str();

3
c_str()dönerconst char*
Steve Jessop

1
doğru ise, std :: string içindeki verileri c_str () ile değiştiremezsiniz (değiştirmemelisiniz). Verileri değiştirmek istiyorsanız, c_str () 'den gelen c string memcpy'd olmalıdır
Carson Myers

11
const char* charPointer = "Hello, World!\n";
std::string strFromChar;
strFromChar.append(charPointer);
std::cout<<strFromChar<<std::endl;

6
char* data;
stringstream myStreamString;
myStreamString << data;
string myString = myStreamString.str();
cout << myString << endl;

5

Kullanıcı tanımlı değişmez değeri kullanan yeni bir yöntemden bahsetmek istiyorum s. Bu yeni bir şey değildir, ancak C ++ 14 Standart Kitaplığı'na eklendiğinden daha yaygın olacaktır.

Genel durumda büyük ölçüde gereksiz:

string mystring = "your string here"s;

Ancak, geniş dizelerle de otomatik kullanmanıza izin verir:

auto mystring = U"your UTF-32 string here"s;

Ve burada gerçekten parlıyor:

string suffix;
cin >> suffix;
string mystring = "mystring"s + suffix;

2

MSVC2005 ile yapıcıyı std::string(char*)en üst düzey cevap gibi kullanmak için mücadele ediyorum . Bu varyantın her zaman güvenilir http://en.cppreference.com/w/cpp/string/basic_string/basic_string üzerinde # 4 olarak listelendiğini gördüğüm gibi , eski bir derleyicinin bile bunu sunduğunu düşünüyorum.

Bu yapıcı mutlakının (unsigned char*)bir argüman olarak eşleşmeyi reddettiğini fark etmem çok uzun sürdü ! std::stringArgüman türüyle uyuşmama ile ilgili bu anlaşılmaz hata mesajlarını aldım , ki bu kesinlikle amaçladığım şey değildi. Sadece tartışmayı std::string((char*)ucharPtr)çözerek sorunumu çözdüm ... duh!


0
char* data;
std::string myString(data);

9
Bu tanımsız davranışa neden olacaktır.

1
Sadece bu iki satırla, databaşlatılmamış olarak kalır (boş).
heltonbiker

1
İşaretçinin gerçek "uzunluğu" olmadan, bu kod kaybolan verilere neden olabilir, std ::
dizginiz

0

Erik'den başka kimsenin neden bundan bahsetmediğinden emin değilim, ancak bu sayfaya göre , atama operatörü gayet iyi çalışıyor. Yapıcı, .assign () veya .append () kullanmaya gerek yoktur.

std::string mystring;
mystring = "This is a test!";   // Assign C string to std:string directly
std::cout << mystring << '\n';

1
İşlevsel olarak çalışıyor gibi görünüyor, ancak bunu yaptığımda programın sonunda =(ve +=) "yeni" birinden kaynaklanan Valgrind ulaşılabilir blokları bildirmeyle ilgili sorunlar almaya başladım . Böyle bir değişmezle değil, sadece char*şeylerle gerçekleşiyor gibi görünüyor . Bu tür raporların gerçekten sızıntı olup olmadığı konusu burada tartışılmaktadır . Ancak destString = std::string(srcCharPtr);valgrind sızıntı raporlarına atamayı değiştirirsem gitti. YMMV.
HostileFork, SE'ye

HostileFork'un yorumu, bir char * (fgets gibi) üzerinden bir dize oluşturmanın std :: string'in bu belleğin ömrünü yönetmesini sağlayacağına inanmanıza neden olabilir. Ancak durum böyle değil. 21.4.2.7 ve .9 standardına bakınız Constructs an object of class basic_string and determines its initial string value from the array. Tamponlar veya işaretçi sahipliği hakkında değer ve hiçbir şey söylemez.
Erik van Velzen
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.