0

I am trying to convert a string into an array in C++. my string is: [1, 2, 3] I need to take out the numbers and put them into an array. What I have tried so far is :

char A[] ={};
short loop = 0;
string line1 = [1, 2, 3];
for(int i = 0 ; i < line1.length(); i++){
  if(line1[i] == '[' || line1[i] == ',' || line1[i] == ' '|| line1[i] == ']')
  continue;
else{

{  A[loop] = line1[i];
loop++;
}}}

For some reason, I don't get the right values.

3
  • 3
    Your string is not what you think. It is not "[1, 2, 3]". It is \01\02\03. Hint: you forgot quotes. Commented Sep 24, 2021 at 8:25
  • 3
    There are many errors in the code you show. Please try to create a minimal reproducible example of your actual attempt. and tell us about the problems you have with it. Commented Sep 24, 2021 at 8:27
  • 1
    As for a possible way to solve what seems to be your problem (get numbers from a string into a vector), replace all unwanted characters in the string with spaces. Then you can use std::istream_iterator to initialize the vector directly. All it takes is a couple of lines of code. Commented Sep 24, 2021 at 8:29

2 Answers 2

2

It is not that clear what you want.

Example: If you have a std::string containing always only 3 numbers, then you can put the string into a std::istringstream and then use the extractraction operator >> to extract the things that you want.

Simple example:

#include <iostream>
#include <string>
#include <sstream>

int main() {
    // Our test string
    std::string line{"[1, 2, 3]"};

    // Here we will store the 3 numbers
    int number1{}, number2{}, number3{};

    // The brackets and the comma will be stored in a dummy variable
    char dummy;

    // Now, put the string into an istringstream, so that we can extract data from it.
    std::istringstream iss{ line };

    // And, extract the values:
    iss >> dummy >> number1 >> dummy >> number2 >> dummy >> number3 >> dummy;

    //Show result:
    std::cout << number1 << '\t' << number2 << '\t' << number3 << '\n';
}

The dummies wild not be used and discarded. You can of course also extract the values from the string and put them directly into a fixed size array

#include <iostream>
#include <string>
#include <sstream>

int main() {
    // Our test string
    std::string line{"[1, 2, 3]"};

    // Here we will store the 3 numbers
    int intArray[3];

    // The brackets and the comma will be stored in a dummy variable
    char dummy;

    // Now, put the string into an istringstream, so that we can extract data from it.
    std::istringstream iss{ line };

    // And, extract the values:
    iss >> dummy >> intArray[0] >> dummy >> intArray[1] >> dummy >> intArray[2] >> dummy;

    //Show result:
    std::cout << intArray[0] << '\t' << intArray[1] << '\t' << intArray[2] << '\n';
}

It is a little bit more difficult, if the count of numbers in the string is variable. So, for example more than 3.

Then you need a kind of variable length array. This is existing in C++ and called std::vector. It can grow dynamically and is used in many many many C++ applications.

Ok, now we know where to store. But, how to continue. First of all, there are many many potential solutions. But an easy one is, to replace the brackets with blanks. The result will be a comma separated list of values. This needs to be split into its components.

For splitting CSV (Comma Seperated Value) strings, there are again many potential solutions. I will show some at the end of this posting.

But for now, I will simply replace all none digits with a space and use a loop to extract all values. The extracted values will be psuhed into the std::vector

#include <iostream>
#include <string>
#include <sstream>
#include <cctype>
#include <vector>

int main() {
    // Our test string
    std::string line{"[1, 2, 3, 4]"};

    // Here we will store the numbers
    std::vector<int> numbers{};

    // Replace all none digits with space
    for (char& c : line) if (not std::isdigit(c)) c = ' ';

    // Now, put the string into an istringstream, so that we can extract data from it.
    std::istringstream iss{ line };

    // And, extract the values:
    int value;
    while (iss >> value) numbers.push_back(value);

    //Show result:
    for (int& n : numbers) std::cout << n << '\t';
}

As said, there are more possible solutions to split a CSV string. Please see 4 adiitional solutions:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <regex>
#include <algorithm>
#include <iterator>
#include <cstring>
#include <forward_list>
#include <deque>

using Container = std::vector<std::string>;
std::regex delimiter{ "," };


int main() {

    // Some function to print the contents of an STL container
    auto print = [](const auto& container) -> void { std::copy(container.begin(), container.end(),
        std::ostream_iterator<std::decay<decltype(*container.begin())>::type>(std::cout, " ")); std::cout << '\n'; };

    // Example 1:   Handcrafted -------------------------------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Search for comma, then take the part and add to the result
        for (size_t i{ 0U }, startpos{ 0U }; i <= stringToSplit.size(); ++i) {

            // So, if there is a comma or the end of the string
            if ((stringToSplit[i] == ',') || (i == (stringToSplit.size()))) {

                // Copy substring
                c.push_back(stringToSplit.substr(startpos, i - startpos));
                startpos = i + 1;
            }
        }
        print(c);
    }

    // Example 2:   Using very old strtok function ----------------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Split string into parts in a simple for loop
#pragma warning(suppress : 4996)
        for (char* token = std::strtok(const_cast<char*>(stringToSplit.data()), ","); token != nullptr; token = std::strtok(nullptr, ",")) {
            c.push_back(token);
        }

        print(c);
    }

    // Example 3:   Very often used std::getline with additional istringstream ------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Put string in an std::istringstream
        std::istringstream iss{ stringToSplit };

        // Extract string parts in simple for loop
        for (std::string part{}; std::getline(iss, part, ','); c.push_back(part))
            ;

        print(c);
    }

    // Example 4:   Most flexible iterator solution  ------------------------------------------------

    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };


        Container c(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
        //
        // Everything done already with range constructor. No additional code needed.
        //

        print(c);


        // Works also with other containers in the same way
        std::forward_list<std::string> c2(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});

        print(c2);

        // And works with algorithms
        std::deque<std::string> c3{};
        std::copy(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {}, std::back_inserter(c3));

        print(c3);
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

0

You need to use quotation marks. string line1 = "[1, 2, 3]" to interpret data as string.

Moreover you can use isdigit function to check if a particular character is a number.

Comments

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.