Ranges und String Split



  • Hi,

    eigentlich eine typische Aufgabe: einen String an einem bestimmten Zeichen splitten.
    Ich habe das mal genutzt um ein bisschen mit std::ranges zu spielen und kann mir das Verhalten nicht erklären.

    Ich splitte ein String an dem Zeichen "/".
    split3 - einfach durchiterieren und ausgeben funktioniert wie man das erwarten würde.
    split1 - dreht die Reihenfolge, kann mir jemand erklären warum? sry, war dumm - Iterator wird inkrementiert und so
    split2 - findet den Trenner nicht und gibt daher als erste Position den ganzen String aus. Ich verstehe, dass ein String eine Range auf char ist und man daher einen char braucht, hätte aber erwartet, dass das dann ein Fehler gibt, da die Typen nicht zusammen passen.

    #include <ranges>
    #include <iostream>
    
    constexpr void split1(const std::string& key)
    {
     auto parts = std::views::split(key,'/');
     if (parts.empty())
       std::cout << "empty";
    
     auto first = parts.begin();
     const auto second = first++;
    
     if (second == std::end(parts))
       std::cout << std::ranges::to<std::string>(*first) << " \n";
    
      std::cout << std::ranges::to<std::string>(*first) << " " <<std::ranges::to<std::string>(*second) << " \n";
    }
    
    constexpr void split2(const std::string& key)
    {
     auto parts = std::views::split(key,"/");
     if (parts.empty())
       std::cout << "empty";
    
     auto first = parts.begin();
     const auto second = first++;
    
     if (second == std::end(parts))
       std::cout << std::ranges::to<std::string>(*first) << " \n";
    
      std::cout << std::ranges::to<std::string>(*first) << " " <<std::ranges::to<std::string>(*second) << " \n";
    }
    
    constexpr void split3(const std::string& key)
    {
     for(auto part : std::views::split(key, '/'))
       std::cout << std::string_view(part) << " ";
     
    }
    
    int main()
    {
     std::string key("test/bla");
     split1(key);
     split2(key);
     split3(key);
    }
    

    Link zum direkt rumspielen: https://godbolt.org/z/sqW58czas



  • Benutze in split2

    using std::operator""sv;
    auto parts = std::views::split(key,"/"sv);
    

    wie auch im Beispiel zu std::ranges::views::split verwendet wird.

    Die Erklärung steht unter "Notes":

    The delimiter pattern generally should not be an ordinary string literal, as it will consider the null terminator to be necessary part of the delimiter; therefore, it is advisable to use a std::string_view literal instead.


Anmelden zum Antworten