Soru Std :: string'in kendisine bir alt yazı atayabilir misiniz?


Geçenlerde bir std::stringiçeriğini bir alt dizesiyle. Burada aramak için en mantıklı işlev bence, http://www.cplusplus.com/reference/string/string/assign/:

altyazı (2) dize ve atama (const string & str, size_t subpos, size_t sublen);
  
  Karakter pozisyonu alt sırasındaki str kısmını kopyalar ve alt karakterleri (veya str'nin çok kısa olması durumunda ya da alt satır string: npos ise) sonuna kadar str.

str
  Değeri kopyalanan veya taşınan başka bir dize nesnesi.

subpos
  Nesneye bir alt yazı olarak kopyalanan str'deki ilk karakterin konumu. Bu str'nin uzunluğundan daha büyükse, out_of_range'ı atar. Not: str'deki ilk karakter 0 (1 değil) değeriyle gösterilir.

sublen
  Kopyalanacak alt dizenin uzunluğu (eğer dize kısasa, mümkün olduğunca çok sayıda karakter kopyalanır).       String :: npos değeri, str'nin sonuna kadar tüm karakterleri gösterir.

Ancak, bu izin verilip verilmeyeceğinden emin değilim, ya da dize verisini bozabilir. bunu biliyorum memcpy()örneğin, bir alanın (bir kısmı) ile bir bellek alanının üzerine yazılmasına izin vermez (ya da en azından bozulmalarını garanti etmez). memcit () vs memmove ()). Ancak, yukarıdaki yöntemin aynı kısıtlamaya sahip olup olmadığını bilmiyorum.

Daha genel olarak, bu sorunun cevabını kendim çözebilseydim, lütfen yorum yapabilir misiniz? Bağlantımdaki belgelerinde hiçbir şey yok, bu sorunun cevabının ne olduğunu açıklığa kavuşturuyor. belki tanımındaki "Başka" niteleyicisi str parametre ("Bir diğeri dize nesnesi "), görünmüyor gibi görünüyor bu Nesne, bunun net olmadığını görmeme rağmen. Bu belgelerin zayıflığı mı?


20
2018-01-25 21:55


Menşei


Atanabilir C ++ sınıfları genellikle kopya atama işlecini güvenli bir şekilde uygular (yani, atamayı kontrol ederler) *this = *this). Standart konteyner sınıfları istisna değildir. Ancak, bu bile gerekli değildir - dizenin bir alt dizesi değil Artık dizenin kendisi. "Cplusplus.com" sitesi, yine de, kötü bir ifadeye sahip gibi görünüyor - cppreference.com Bunun yerine "yerine geçen" kelimesini kullanır, bunun yerine yaptığınız şeyin güvende olması oldukça açıktır. - The Paramagnetic Croissant
@ TheParamagneticCroissant, neden "değiştirir" sözcüğü güvenli olması gerektiğini açıklığa kavuşturuyor? Aynı şekilde, bunu söyleyebilirsin. memcpy() Hedef arabellek içeriğini değiştirir, ancak bu güvenli olduğu anlamına gelmez. - bgoldst
@bgoldst Bu senaryonun standart tarafından tam olarak karşılanmadığından emin olmak için çalışıyorum. Güvende kalmak istiyorsan, kullan substr ve atama operatörü (yani bir kopya ile çalışır). - Columbo
@dyp Ne yazık ki bu yeterli değil. Belki bu bir EWG konusunun konusu olmalıdır. - Columbo
@Columbo Sanırım bunun sonu gibi olabilir LWG 526. - dyp


Cevaplar:


Yok hayır.

Bu işlem, [string :: assign] / 4 ile tanımlanır:

basic_string& assign(const basic_string& str, size_type pos,
    size_type n = npos);

Etkileri: Etkin uzunluğu belirler rlen atanacak dizenin   daha küçük olarak n ve str.size() - pos ve aramalar assign(str.data() + pos rlen).

(dat yazım hatası)

Sonra:

basic_string& assign(const charT* s, size_type n);

Etkileri: Tarafından kontrol edilen dizgenin yerini alır. *this bir dizeyle   uzunluk n kimin elemanları tarafından işaret edilenlerin bir kopyası s.

Bununla ilgili hiçbir şey, hakkında bir şey söylemiyor str.assign(str, 0) hiç güvenli değil (özellikle, bilmemizin bir yolu yok) ne zaman her karakterin kopyası oluşacaktır!).

Bu yüzden bunu yapmamanızı şiddetle tavsiye ederim.


1
2018-01-25 22:39



İçin vector::push_back vs, herhangi bir gerekliliğin ihmal edilmesinin iyi huylu olduğunu garanti ettiği ileri sürülmüştür (başarısız olmasına izin verilmemektedir). libstdc ++ ve libc ++, takma dizeleri açıkça atamayı destekliyor gibi görünüyor. - dyp
@dyp: Bir gereksinimin ihmal edilmesinin bir şartı nasıl zorunlu hale getirdiğini görmüyorum! Öyleyse, ön koşul belirtilmezse, o zaman hiç kimsenin bulunmadığını varsayabilirim. Fakat bu tüm tahmininizdir, ve özellikle bu özel olarak ele alınmadıkça, tanım gereği güvensiz olduğu sonucuna varmak isterim. - Lightness Races in Orbit
@dyp Bağlantınızı okuduktan sonra söylemek üzereydim. İddiaların makul olduğu sürece çağrının iyi olması gerektiğine inanıyorum. - Columbo
@Columbo, bir dizenin bir parçasını kendisine atarken her zaman çakışır, çünkü bir dizenin bir parçasını kendisine atarsınız. - OmnipotentEntity
Spesifik olduğunu düşünüyorum. "Dizeyi değiştirir ... elemanları kimin tarafından işaret edilenlerin bir kopyasıdır"- bu demektir ki uygulama gereklidir Bu etkiye sahip olduğundan emin olmak için. Önkoşullar, çakışan girdilerden bahsetmez. Bu nedenle, örtüşen girdilerle onu aramak güvenli olmalıdır çünkü uygulama şart açıklanan etkiye sahip olmak - sehe