vesii
vesii

Reputation: 3128

Converting char* to an array of strings by splitting

I want to convert a char* line of commands into a string array. What I tried:

void parse(char* cmd, int length) {
    std::string *arguments = nullptr;
    int amount = 0;
    for (int i = 0; i < length; i++) {
        if (cmd[i] == ' ' || cmd[i] == '\t' || cmd[i] == '\n') {
            amount++;
            continue;
        }
        arguments[amount] = cmd[i];
    }
}

But I'm not sure about the std::string *arguments = nullptr; part. I don't know the amount of arguments in the cmd so I'm not sure how to initialize properly the arguments array. In C I probably should solve it with malloc but how do I solve it in C++? Also, as I want to return arguments and amount, how can I pass them as arguments references to the parse string?

Upvotes: 0

Views: 67

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595981

You are not allocating any memory for arguments to point at. Use std::vector<std::string> instead of std::string*. Also see Splitting strings in C++.

Try something more like this:

#include <string>
#include <vector>
#include <cctype>

std::vector<std::string> parse(const char* cmd, int length) {
    std::vector<std::string> arguments;
    const char *start = cmd;
    const char *stop = cmd + length;
    while (start < stop) {
        while ((start < stop) && isspace(*start)) ++start;
        if (start == stop) break;
        const char *end = start + 1;
        while ((end < stop) && !isspace(*end)) ++end;
        arguments.push_back(std::string(start, end-start));
        start = end + 1;
    }
    return arguments;
}

Live Demo

Alternatively, operator>> handles whitespace parsing for you, so you can wrap the cmd data inside of a std::istringstream and loop through that instead, eg:

#include <string>
#include <vector>
#include <sstream>

std::vector<std::string> parse(char* cmd, int length) {
    std::vector<std::string> arguments;
    std:istringstream iss(std::string(cmd, length));
    std::string s;
    while (iss >> s) {
        arguments.push_back(s);
    }
    return arguments;
}

Live Demo

Upvotes: 4

Related Questions