Home > Blockchain >  Splitting string with colons and spaces?
Splitting string with colons and spaces?

Time:12-15

So I've made my code work for separating the string:

const char  one[2] = {'s', 'o'};
const char *two[2] = {"...", "---"};
  
char ip(String m) {
    for (int i = 0 ; i < 2 ; i  ) {
        if (strcmp(m.c_str(), two[i]) == 0) {
            return one[i];
        }
    }
}

String ipRe(char d[]) {
    int count = 0;
    char *k = d;
 
    for (count = 1; k[count]; k[count] == ':' ? count   : *k  ) {}
 
    // Serial.println(count);
  
    char *ex[count] = {NULL};
    ex[0] = strtok(d, ":");
 
    int i = 0;
 
    while (i < count) { // 3
        i  ;
        ex[i] = strtok(NULL, ":");
    }
 
    String c;
 
    for (int j = 0 ; j < count; j  ) {
        c  = ip(ex[j]);
    }
  
    return c;                      
}

void setup() {
    Serial.begin(9600);
    Serial.println(ipRe("...:---:..."));
}

Returns "sos" as it should, but how can I split the string if it has a space (or multiple spaces) like:

Serial.println(ipRe("..:---:... ..:---:..."));

So it returns "sos sos"? (Currently returns "so os")

I have had no luck with this, so any help would be greatly appreciated!

CodePudding user response:

I'd suggest using <regex> library if the compiler of yours supports C 11.

#include <fstream>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <regex>

const std::regex ws_re(":|  ");
void printTokens(const std::string& input)
{
    std::copy( std::sregex_token_iterator(input.begin(), input.end(), ws_re, -1),
               std::sregex_token_iterator(),
               std::ostream_iterator<std::string>(std::cout, "\n"));
}

int main()
{
    const std::string text1 = "...:---:...";
    std::cout<<"no whitespace:\n";
    printTokens(text1);

    std::cout<<"single whitespace:\n";
    const std::string text2 = "..:---:... ..:---:...";
    printTokens(text2);

    std::cout<<"multiple whitespaces:\n";
    const std::string text3 = "..:---:...   ..:---:...";
    printTokens(text3);
}

The description of library is on cppreference. If you are not familiar with regular expressions, the part in the code above const std::regex ws_re(":| "); means that there should be either ':' symbol or (or in regular expressions denoted by pipe symbol '|') any amount of whitespaces (' ' stands for 'one or more symbol that stands before the plus sign'). Then one is able to use this regular expression to tokenize any input with std::sregex_token_iterator. For more complex cases than whitespaces, there is wonderful regex101.com.
The only disadvantage I could think of is that regex engine is likely to be slower than simple handwritten tokenizer.

CodePudding user response:

I would simply add a delimiter to your tokenizer. From a strtok() description the second parameter "is the C string containing the delimiters. These may vary from one call to another".

So add a 'space' delimiter to your tokenization: ex[i] = strtok(NULL, ": "); trim any whitespace from your tokens, and throw away any empty tokens. The last two shouldn't be necessary, because the delimiters won't be part of your collected tokens.

  • Related