2016-03-30 30 views
1

dize göz önüne alındığında find(cbegin(foo), cend(foo), [](const auto& i) { return isspace(i); })Yerel ayarlarımın Whitespaces dizisini nasıl alabilirim? Ben yaparak boşluk için bir yineleyici bulabilirsiniz <code>const auto foo = "loremtipsum"s</code></p> <p>:

Ama pozisyon istiyorum.

  1. Kullanım distance: distance(cbegin(foo), find(cbegin(foo), cend(foo), [](const auto& i) { return isspace(i); }))
  2. isspace bakın ve bu içeriği bir kodlanmış dize oluşturmak: Açıkça foo.find_first_of(" \f\n\r\t\v")

basittir ve bu dönecektir Bunun için iki seçenek vardır string::npos için 'u test etmek zorundayım, ancak yerel dizimden dizgiyi harcalamak yerine bir dizi tüm boşlukları sağlamasını istemek istiyorum. Bu dizeyi elde etmek için kullanabileceğim bir işlev mi yoksa onu pişirmenin bir yolu var mı?

+1

* Açıkça * seçenek 2 daha mı basit? Huh. Ben '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '']. – Voo

+0

@Voo * Açıkça *. 'Uzaklık 'konumlarıyla çalışırken sinir bozucu olduğunu ekledim çünkü aynı zamanda' foo.size() 'dan daha büyük olup olmadığını da kontrol etmeliyim, böylece' string :: npos 'olarak ayarlayabilirim Eğer gerekliyse. –

+1

Seçenek 3: 'distance' yöntemini kullanan ve kodunuzda kullanan kendi işlevinizi (" first_space "veya benzeri bir şey) yazın. – molbdnilo

cevap

1

Bu yarı naif bir yaklaşımdır ama biz char bir ürünle yerel ayar ile tutabilir tüm olası değerlerine karşı isspace() denetler ve sadece true dönmek değerleri tutan bir dize döndüren bir işlev olabilir. Bu dizeyi 2. seçenekle kullanabilirsiniz.

Bu, N == std::numeric_limits<char>::max() - std::numeric_limits<char>::min() numaralı O (N) işlemidir, ancak yerel ayarı değiştirmezseniz, bunu yalnızca bir kez çalıştırmanız ve dizeyi yakalamanız gerekir.

std::string whitespace = whitespace_string(std::locale("")); 

ile

std::string whitespace_string(const std::locale& loc) 
{ 
    std::string whitespace; 
    for (char ch = std::numeric_limits<char>::min(); ch < std::numeric_limits<char>::max(); ch++) 
     if (std::isspace(ch, loc)) 
      whitespace += ch; 
    // to avoid infinte loop check char max outside the for loop. 
    if (std::isspace(std::numeric_limits<char>::max(), std::locale(loc))) 
     whitespace += std::numeric_limits<char>::max(); 
    return whitespace; 
} 

Ve bunu kullanarak Asistan geçerli yerelde tüm beyaz boşluk karakterleri ile bir dize verir. Geçerli yerel ayarı kullanmak istemiyorsanız,'u std::locale("C") gibi farklı bir yerel ayar ile değiştirebilirsiniz.

+0

Bunu "constexpr" yapabilir miyiz? Derleme zamanında 'cout'un yerel ayarını alabileceğimden emin değilim? –

+1

@JonathanMee Bunun, "std :: string", çalışma zamanı tahsisine bağlı olduğu için "constexpr" yapılabileceğini sanmıyorum. Onlarla çok fazla deneyimim olmadı. – NathanOliver

+0

Dar karakterler son milenyumdur. Ve onları bilinmeyen bir yerel ayarda kullanıyorsunuz ... –