2016-03-28 19 views
2

Boş olmayan sonlandırma dizelerini döndüren bazı eski işlevler var.Boş olmayan sonlandırıcı c dizesini c dizgisini sonlandırmaya dönüştürmenin en temiz yolu

struct legacy { 
    char a[4]; //not null terminated 
    char b[20]; //not null terminated 
}; 

Bu char dizileri çok geziyorum ve sıfır sonlandırmaya dönüştürmek için temiz bir yola ihtiyacım var. şu anda bu tarihi itibariyle

ne yaptığımı geçerli:

legacy foo; 
std::string a(foo.a, sizeof(foo.a)); 
std::string b(foo.b, sizeof(foo.b)); 
bar(foo.a.c_str(), foo.b.c_str()); 

Ben böyle bir şey için bu kodu azaltmak için sınıflar ve şablonlar kullanabilirsiniz daha temiz bir yolu var mı ...

legacy foo; 
bar(make_null_terminated(foo.a), make_null_terminated(foo.b)); 
+0

mu geçici dizeleri yok 'bar()' sadece 'const char *' almak? Onlara tutun mu yoksa ntbs'lerin ömrü, 'bar() 'aramasını geçmemeli mi? – Barry

+0

@Barry bar sadece bir 'const char * 'alır – andre

+0

Başka bir şey almak için değiştirebilir misiniz yoksa kontrolünüz dışında mı? – Barry

cevap

7

şey yapmalıdır:

struct make_null_terminated { 
    template <size_t sz> 
    make_null_terminated(char (&lit)[sz]) : str(lit, sz) {} 
    operator const char*() const { return str.c_str(); } 
private: 
    std::string str; 
} 

Bu, istediğiniz şekilde kullanmanıza olanak tanır.

DÜZENLEME etiketler düzenlemek sonra std::begin ve std::endl kurtuldum.

0

sadece yapabilirsiniz: böyle

std::string a(std::begin(foo.a), std::end(foo.a)); 
+0

std :: end, zaten boş bir sonlandırma karakterine sahip olduğumuzu varsayar mı? – andre

+0

Sanırım sorunun noktasını kaçırıyorsunuz - bu bir işleve (şablon) kapılabilir mi? –

+0

@andre: Olmaz. –

0

Düşünebildiğim en temiz yol, std :: string iterator yapıcısını kullanmaktır, bir işaretçi bir çeşit yineleyici.

bar(std::string(std::begin(foo.a), std::end(foo.a)).c_str(), 
    std::string(std::begin(foo.b), std::end(foo.b)).c_str()); 

Burada neler oluyor?

  1. foo.a olarak bayt kopyalama ve ekleyerek bir dizi oluşturmak bir arka sıfır

  2. aynen foo.b

  3. çağrı için (bu std :: string içinde kapsüllenir) Geçici dizelerdeki c_str() yöntemi, içindeki null sonlandırılmış c-stringine bir işaretçi alır.

  4. çağrı çubuğu

+0

Tooooo çok yazarak :) – SergeyA

+0

@SergeyA iki kez ölçün, bir kez kesin. O zaman ne kadar yazmanız önemli değil - bir daha dokunmanıza asla gerek kalmayacak. –

+0

"Miras" dan veriye ihtiyaç duyan bir işlevin her çağrılması için. Bence, OP'nin birden fazlası var. – SergeyA