0

Note: I am working using C++11 standard

I am looking to write a function that handles the following problem:

Given the following input: a,b,c I want it to print a and b and c

Given: a,b,c, I want it to print a and b and c and ""

Given: ,a I want it to print "" and a

Given , it should print "" and in case of empty string it shouldn't print anything

In other words I want to extract every value between two , plus to take care of the edges.


My current implementation is so buggy and I had edited it more than 8 times since I always find some edge cases.

void print(const string &command)
{
        string vertex_title = "";
        int i = 0;
        while (i < command.lengh()) {
        if (command[i] == ',') {
            if (i==command.lengh()-1) return false;
            std::cout<<vertex_title;
            vertex_title = "";
            i++;
            continue;
        }
        vertex_title += command[i++];
}

Note: I don't know but maybe regex help here (I know nothing about it)

  • Show a minimal compilable example. What is `splitter_index`? What is `vertex_title`? Explain the problem. What bugs do you find? Also, you should take the argument by `const&` to avoid wasting CPU copying it. – underscore_d Aug 05 '20 at 11:41
  • 1
    Does this answer your question? [Split a string using C++11](https://stackoverflow.com/questions/9435385/split-a-string-using-c11) – Roberto Trani Aug 05 '20 at 11:43
  • 1
    Not really. What is `lengh()`? Where is the final brace of that `while` loop? – underscore_d Aug 05 '20 at 11:44
  • Construct a `std::istringstream` from that string and then use https://en.cppreference.com/w/cpp/string/basic_string/getline to read fields, with comma as delimiter. – bipll Aug 05 '20 at 11:44
  • @bipll are you sure you got me the correct link? getline won't split string –  Aug 05 '20 at 11:53
  • You can use [boost::algorithm::split](https://www.boost.org/doc/libs/1_73_0/doc/html/boost/algorithm/split.html) or [std::strtok](https://en.cppreference.com/w/cpp/string/byte/strtok) – Thomas Sablik Aug 05 '20 at 11:54
  • @daniel It will read until the specified delimiter, and extract until there, so you can call it again to get the next field. – underscore_d Aug 05 '20 at 11:55
  • @daniel A function with the return type void may not have a return statement with a non-void expression like return false; – Vlad from Moscow Aug 05 '20 at 11:59

2 Answers2

0

While you could implement such a function, I'd strongly suggest using existing solutions. There are quite a few.

I'm personally used to absl::StrSplit() (see https://abseil.io/docs/cpp/guides/strings) which by default will do what you want.

Thomas Sablik also wrote in a comment:

You can use boost::algorithm::split or std::strtok

chakaz
  • 261
  • 2
  • 13
  • 1
    100% do not use `strtok()` or other leftover C bits. And there is already a way to do this without pulling in any external library. – underscore_d Aug 05 '20 at 12:11
0

I guess you need this. Even though it's ugly. You can run and debug it step by step.

#include <iostream>
#include <string>
using namespace std;

void print(const string &command)
{
    std::string vertex_title = "";
    int i = 0;
    while (i < command.size()) {
        if (command[i] == ',') {
            cout << vertex_title;
            vertex_title = "";
        }
        else {
            vertex_title += command[i];
        }
        ++i;

        if (i == command.size())
            cout << vertex_title;
    }
}

int main()
{
    print("a,b,c");
    print("a,b,c,");
    print(",a");
    print(",");

    return 0;
}
Albert
  • 29
  • 1
  • 5