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.