CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Sep 2021
    Posts
    2

    Is there a function intended to split strings by a delimiter in VC++?

    Even if not part of the official C++ standard, does MS VC++ have any functions designed to split a C++ string (variable of type std::string) into an array of strings, where each entry of that array is one of delimited entries in the original single string?

    I know for certain that MS VB6 has such a function, called Split. The syntax for it is ArrayOfStrings=Split(OriginalString,Delimiter). Delimiter is a string of one or more characters that appear in the string OriginalString, and are used to split apart separate entries in a set of data that is stored in that string. ArrayOfStrings is an array, where each entry in the array is a substring that was cut out of the string OriginalString by the Split function, which used the Delimiter string to know where to cut OriginalString for extracting these substrings.

    Does MS VC++ have a function equivalent to VB6's Split function?

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Victor Nijegorodov

  3. #3
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Note that strtok changes the data and cannot be nested. It needs to be used with std::string:ata() (C++17 and later only) as it is a c function.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    Feb 2017
    Posts
    677

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Quote Originally Posted by Ben321 View Post
    Even if not part of the official C++ standard, does MS VC++ have any functions designed to split a C++ string (variable of type std::string) into an array of strings,
    C++ 20 has a new feature called ranges. It has a function for splitting called std::ranges::split_view,

    https://en.cppreference.com/w/cpp/ra...iew/split_view

    I tried the last part of the example shown there,

    Code:
    #include <string_view>
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    #include <iomanip>
    #include <ranges>
    #include <vector>
    #include <array> 
    
    int test() {
            constexpr std::string_view JupiterMoons{"Callisto, Europa, Ganymede, Io, and 75 more"};
            constexpr std::string_view delim{", "};
            std::ranges::split_view moons_extractor{ JupiterMoons, delim }; // (3)
            for (const std::string_view moon : moons_extractor) {
                std::cout << std::quoted(moon) << ' ';
            }
    }
    Unfortunately VS 2019 (the latest download) will not compile it (complaint underlined in the code above). I have no idea what's wrong, and I don't have time to figure it out right now.

    Another option is to use the Boost string library,

    https://www.boost.org/doc/libs/1_77_...ring_algo.html

    It has a split function of the kind you requested. The Boost libraries have a good reputation and many end up as part of the C++ standard eventually.
    Last edited by wolle; September 20th, 2021 at 06:33 AM.

  5. #5
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Is there a function intended to split strings by a delimiter in VC++?

    This compiles OK:

    Code:
    #include <string_view>
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    #include <sstream>
    #include <iomanip>
    #include <ranges>
    
    int main() {
    	constexpr std::string_view JupiterMoons {"Callisto, Europa, Ganymede, Io, and 75 more"};
    	constexpr std::string_view delim {", "};
    	const auto moons {std::views::split(JupiterMoons, delim)};
    
    	for (const auto& m : moons) {
    		std::ostringstream oss;
    
    		std::ranges::copy(m, std::ostream_iterator<char>(oss, ""));
    		std::cout << std::quoted(oss.str()) << ' ';
    	}
    
    	std::cout << '\n';
    }
    Code:
    "Callisto" "Europa" "Ganymede" "Io" "and 75 more"
    The issue seems to be with the type of m. It's not std::string_view but seems to be some variation of std::initializer_list.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    Join Date
    Feb 2017
    Posts
    677

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Quote Originally Posted by 2kaud View Post
    The issue seems to be with the type of m. It's not std::string_view but seems to be some variation of std::initializer_list.
    The code in my post #4 is directly from cppreference.com so either they or VS 2019 has it wrong.

    Anyway, using your suggestion I got this to work in VS 2019 (latest download),

    Code:
    #include <string_view>
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    #include <iomanip>
    #include <ranges>
    #include <vector>
    #include <array> 
    
    inline std::vector<std::string> my_split(const std::string& str, const std::string& delim) {   // traditional split function using ranges
    	std::vector<std::string> vec;
    	std::ranges::split_view extractor{str, delim};
    	for (const auto& e : extractor) {
    		std::ostringstream oss;
    		std::ranges::copy(e, std::ostream_iterator<char>(oss, ""));
    		vec.emplace_back(oss.str());
    	}
    	return vec;
    }
    
    void test() {
    	std::string JupiterMoons{"Callisto, Europa, Ganymede, Io, and 75 more"};
    	std::string delim{", "};
    
    	std::vector<std::string> splitted = my_split(JupiterMoons, delim);
    	for (const std::string& s : splitted) {
    		std::cout << std::quoted(s) << ' ';
    	}
    	std::cout << std::endl;
    }
    Last edited by wolle; September 20th, 2021 at 09:51 AM.

  7. #7
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Is there a function intended to split strings by a delimiter in VC++?

    The code in my post #4 is directly from cppreference.com so either they or VS 2019 has it wrong.
    That code doesn't compile with any of the compilers used with godbolt (gcc/clang et al)... However I'm not convinced that the compilers are currently totally conforming for std::ranges.

    From MSDN:

    The ranges examples require the /std:c++latest compiler option. Because post-release updates to <ranges> in the C++20 Standard are a work in progress, the features that require std::views aren't enabled yet under /std:c++20.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  8. #8
    Join Date
    Feb 2017
    Posts
    677

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Quote Originally Posted by 2kaud View Post
    However I'm not convinced that the compilers are currently totally conforming for std::ranges.
    I guess we need to be patient. Rome wasn't built in one day!

  9. #9
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Even simpler:

    Code:
    #include <string_view>
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    #include <iomanip>
    #include <ranges>
    
    int main() {
    	constexpr std::string_view JupiterMoons {"Callisto, Europa, Ganymede, Io, and 75 more"};
    	constexpr std::string_view delim {", "};
    	const auto moons {std::views::split(JupiterMoons, delim)};
    
    	for (const auto& m : moons) {
    		std::string os;
    
    		std::ranges::copy(m, std::back_inserter(os));
    		std::cout << std::quoted(os) << ' ';
    	}
    
    	std::cout << '\n';
    }
    Code:
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    #include <iomanip>
    #include <ranges>
    #include <vector>
    
    inline auto my_split(const std::string& str, const std::string& delim) {   // traditional split function using ranges
    	std::vector<std::string> vec;
    	std::ranges::split_view extractor {str, delim};
    
    	for (const auto& e : extractor) {
    		std::string os;
    
    		std::ranges::copy(e, std::back_inserter(os));
    		vec.emplace_back(os);
    	}
    
    	return vec;
    }
    
    int main() {
    	const std::string JupiterMoons {"Callisto, Europa, Ganymede, Io, and 75 more"};
    	const std::string delim {", "};
    	const auto splitted {my_split(JupiterMoons, delim)};
    
    	for (const auto& s : splitted)
    		std::cout << std::quoted(s) << ' ';
    
    	std::cout << '\n';
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #10
    Join Date
    Feb 2017
    Posts
    677

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Quote Originally Posted by 2kaud View Post
    Even simpler:
    Even simpler still. I found a way to get rid of the temporary string.

    No string constructor accepts the loop variable e directly. But e can deliver the starting address and length of a char sequence, and for this, there is a string constructor.

    Code:
    inline auto my_split(const std::string& str, const std::string& delim) {   // traditional split function using ranges
    	std::vector<std::string> vec;
    	for (const auto& e : std::ranges::split_view(str, delim)) {
    		vec.emplace_back(std::string(&*e.begin(), std::ranges::distance(e)));
    	}
    	return vec;
    }
    This should allow emplace_back to construct the string in place inside the vector. It could be faster than first constructing the string outside the vector and then moving it inside. I'm not 100% certain about this and the compiler probably produces the same optimized code in both cases anyway,

  11. #11
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Nice - using &*

    The underlying issue is with .end() which doesn't seem to be as expected. But using the &* trick you can remove the need to construct the string, giving just:

    Code:
    inline auto my_split(const std::string& str, const std::string& delim) {   // traditional split function using ranges
    	std::vector<std::string> vec;
    
    	for (const auto& e : std::ranges::split_view(str, delim))
    		vec.emplace_back(&*e.begin(), &*e.begin() + std::ranges::distance(e));
    
    	return vec;
    }
    which I think is as good as we're going to get at the moment.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  12. #12
    Join Date
    Feb 2017
    Posts
    677

    Re: Is there a function intended to split strings by a delimiter in VC++?

    Quote Originally Posted by 2kaud View Post
    Nice - using &*
    Yes, I wish I had come up with it myself .

    I found it in the answer here,

    https://stackoverflow.com/questions/...tdstring-views

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured