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.
CodePudding user response:
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;
}
CodePudding user response:
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.