i were using gmatch in lua to split items, and the slots into their own table like data[1] data[2] the data come from DB however now that i moved to C i can't find the right way to do that. i already waste like 5 day's trying to figure how to do it.
this is what i were using on lua to split the needed data
`
local function stringsplit(inStr,sep)
local rettab = {}
for str in string.gmatch(inStr, "[^;] ") do
table.insert(rettab, str)
end
return rettab
end
here is an example of the the data i need to split correctly
1:200000;2:200001;3:200002
1 , 2 , 3 are the ITEM SLOT : the separator and 200000-200002 the items
so i want to store them separated, "SLOTS" in DATA[1] and ITEMS in DATA[2] (only has example)
the desired result should be something like
DATA[1] // SLOT
1
2
3
DATA[2] //ITEMS
200000
200001
200002
i'm sorry for my bad english, i tried, i would be so happy if someone know the solution or a way to do it properly thanks you :/
CodePudding user response:
See code below using the strtok() function and my own function mySplit(). Consider creating your own implementation or tweak mySplit() to save the words in an array.
#include <iostream>
#include <cstring>
using namespace std;
#define MAX_STR 128
char* mySplit(char* strg, char delimiter=' ')
{
if (NULL == strg) return "\n"; // no string to split passed
//cout << " len: " << strlen(strg);
int len = strlen(strg);
for(int i=0; i<len; i ) {
if (strg[i] == delimiter)
strg[i] = '\n';
}
return strg;
}
int main()
{
char str[MAX_STR] = "This is a string to split";
//cout << " Text to Split: " <<endl;
//cin.getline(str, 100); // get string to split
char *ptr; // pointer to iterate over the src string
ptr = strtok(str, " "); // use strtok() to split.
cout << " \n Split withstring strtok() : \n" << endl;
int cnt = 0; // make sure loops terminate.
// use while loop to check ptr is not null
while (ptr != NULL && cnt < MAX_STR)
{
cout << ptr << endl; // print the string token
ptr = strtok (NULL, " ");
cnt;
}
strcpy(str, "Second test string to split using mySplit()");
ptr = mySplit(str, ' ');
cout << endl << ptr << endl;
return 0;
}
Output: Split withstring strtok() :
This
is
a
string
to
split
Second
test
string
to
split
using
mySplit()
CodePudding user response:
I usually do something like this, which returns a collections of string_views. Which is quite memory efficient. (But it requires the original string to stay in scope).
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
std::vector<std::string_view> split_string(const std::string_view input, char delimiter)
{
std::vector<std::string_view> splits;
const char* p{ input.data() };
const char* word_begin{ p };
std:size_t len{ 0u };
for( auto p = input.data(); *p != 0; p)
{
if (*p == delimiter)
{
if (len > 0ul) splits.emplace_back(word_begin, len);
word_begin = p 1;
len = 0ul;
}
else
{
len;
}
}
if (len > 0ul) splits.emplace_back(word_begin, len);
return splits;
}
int main()
{
auto splits = split_string("This is a string to split", ' ');
for (const auto split : splits)
{
std::cout << split << "\n";
}
return 0;
}