0

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?

7
  • @esii Does cmd point to a string? Commented May 4, 2020 at 21:01
  • 1
    Prefer to use vector. Avoiding vector in C++ similar to avoiding memset and strcmp in C. Commented May 4, 2020 at 21:02
  • 1
    If your first thought is to use malloc in C, then your first though in C++ should be use use std::vector or std::unique_ptr Commented May 4, 2020 at 21:03
  • 2
    'How do I solve it in C++?' Use a vector of strings, std::vector<std::string> arguments;. Use push_back to add strings to the vector and push_back to add characters to the string. Commented May 4, 2020 at 21:03
  • 2
    Usage of std::istringstream and std::vector<std::string> makes this a trivial operation. Commented May 4, 2020 at 21:03

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

4 Comments

Type of the argument should be changed to const char *
Thank you! I'm trying to pass char* arguments[MAX]; but for some reason I get a mismatch. Do you know why?
@vesii That's an array of char* but your function takes a char*
@vesii Are you trying to populate a char*[] array that you pass in, or are you trying to parse such an array? You need to be more specific. Please edit your question with more details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.