Home > other >  String incompatibility issues c
String incompatibility issues c

Time:01-04

I am trying to create a function that will take in a long string with " " and "," dividing different elements gained from a text file. "," represents a new line and " " represents the end of a number in the line. once split the strings should be part of an array.

string* splitstr(string text, string deli = " ")
{
    int start = 0;
    int end = text.find(deli);
    string *numbers[end];
    for (int i = 0; end != -1; i  )
    {
        numbers[i] = text.substr(start, end - start);
        start = end   deli.size();
        end = text.find(deli, start);
    }
    return numbers;
}

However I am facing a problem where I get this:

cannot convert 'std::string**' {aka 'std::__cxx11::basic_string<char>**'} to 'std::string*' {aka 'std::__cxx11::basic_string<char>*'} in return

How can I resolve this, or improve my function?

I was expecting to be able to store string elements in a string array and make the function return the array. I'm fairly new to programming and I started off with java so this logic might not work in c .

CodePudding user response:

You should avoid using arrays like this and instead use a vector

like as follows:

std::vector<std::string> splitstr(const std::string & text, const std::string & deli = " ")
{
    int start = 0;
    int end = text.find(deli);
    std::vector<std::string> numbers;
    for (int i = 0; end != -1; i  )
    {
        numbers.push_back(text.substr(start, end - start));
        start = end   deli.size();
        end = text.find(deli, start);
    }
    return numbers;
}

note this will not get the last item in the string if there is not a delimiter after it.

CodePudding user response:

Use a combination of std::vector and std::string_view. A string_view avoids the need to allocate new output strings, the caveat is that you can only use the split result if the original input string is still in memory.

#include <iostream>
#include <string>
#include <string_view>
#include <vector>
#include <set>

// returns vector of string views to avoid copying of string data
// this function can split on multiple delimiters.

auto split_string(std::string_view input, std::string_view delimiters)
{
    std::vector<std::string_view> substrings;
    std::size_t substring_len{ 0ul };

    // string_view can be constructed from a pointer and a length
    auto start_of_substring_ptr = input.data();
    auto current_char_ptr = input.data();

    // use range based for to never run beyond end of input string
    for (const char c : input)
    {
        // if a delimiter is found
        if (delimiters.find(c) != std::string::npos)
        {
            if (substring_len != 0ul)
            {
                // add another string_view to the output
                substrings.emplace_back(start_of_substring_ptr , substring_len);
            }

            // assume the next substring will start after this delimter
            // if there are multiple delimiters in a row it will just move ahead
            start_of_substring_ptr = current_char_ptr   1;
            substring_len = 0ul;
        }
        else
        {
            substring_len  ;
        }

        current_char_ptr  ;
    }

    return substrings;
}


int main()
{
    std::string input{ "Time flies when you are having fun, kermit said!"};

    for (const auto& substring : split_string(input, " ,!"))
    {
        std::cout << substring << "\n";
    }

    return 0;
}
  • Related