I'm struggling with this split function based on C. After returning the struct by reference from the strSplit() function the token handle seems wrong. The variable sd->tokens is the right address, but I cannot get the tokens. But they are correct because inside the function I can get it. How can I resolve this and what is the reason for this behavior. All remaining variables in the struct are ok.
#include <stdio.h>
#include <string.h>
struct splitResult {
char *source;
long lSource;
int result;
char **tokens;
};
typedef struct splitResult splitResultStruct;
splitResultStruct * strSplit(char *source, char *delimiter);
int main(int argc, const char * argv[]) {
char *source = "part1.part2.part3";
splitResultStruct *sd;
sd = strSplit(source, ".");
printf("%d tokens found\n", sd->result);
for(int i=0; i<sd->result; i ) {
printf("%s\n", sd->tokens[i]);
}
return 0;
}
splitResultStruct * strSplit(char *source, char *delimiter) {
// Defines the result struct
splitResultStruct sData, *sDataPtr;
sDataPtr = &sData;
sData.source = source;
// Gets the length of source string
sData.lSource = strlen(source);
// Don't split if empty string is given
if(sData.lSource == 0) {
sData.result = -1;
return sDataPtr;
}
// Allocate memory according teh size of source string
char data[sData.lSource];
// Copy the source into the allocated memory
strcpy(data,source);
// Just count the tokens
char *token = strtok(data, delimiter);
int tc = 0;
while (token != NULL)
{
token = strtok(NULL, delimiter);
tc ;
}
if(tc == 0) {
sData.result = -1;
return sDataPtr;
}
// Defines an array of char pointer with the dimension of the number of tokens
sData.result = tc;
char *tokens[tc];
// Resets the token engine
strcpy(data,source);
// Strip out the first token found
token = strtok(data, delimiter);
tokens[0] = token;
tc = 0;
while (token != NULL)
{
// Strip out one token and store them into the token array
token = strtok(NULL, delimiter);
tc ;
tokens[tc] = token;
}
sData.tokens = tokens;
for(int i=0; i<sData.result; i ) {
printf("%s\n", sData.tokens[i]);
}
return sDataPtr;
}
CodePudding user response:
Remember, never return a pointer to local variable. Local variables are destoryed when the function returns.
Try:
sDataPtr = malloc(sizeof(splitResultStruct));
Or:
static splitResultStruct sData;
splitResultStruct* sDataPtr;
CodePudding user response:
Ok, guys, got it regarding the struct memory. Changed the code to this version, so the struct will be declared in main and a pointer is passed. The functions returns nothing but changes the struct itself. But the tokens remains empty. Not a clue...
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct splitResult {
char *source;
long lSource;
int result;
long tSize;
char **tokens;
};
typedef struct splitResult splitResultStruct;
void strSplit(splitResultStruct *, char *source, char *delimiter);
int main(int argc, const char * argv[]) {
char *source = "part1.part2.part3";
splitResultStruct sd;
strSplit(&sd, source, ".");
printf("%d tokens found\n", sd.result);
for(int i=0; i<sd.result; i ) {
printf("%s\n", sd.tokens[i]);
}
return 0;
}
void strSplit(splitResultStruct *sData, char *source, char *delimiter) {
sData->source = source;
// Gets the length of source string
sData->lSource = strlen(source);
// Don't split if empty string is given
if(sData->lSource == 0) {
sData->result = -1;
}
// Allocate memory according teh size of source string
char data[sData->lSource];
// Copy the source into the allocated memory
strcpy(data,source);
// Just count the tokens
char *token = strtok(data, delimiter);
int tc = 0;
while (token != NULL)
{
token = strtok(NULL, delimiter);
tc ;
}
if(tc == 0) {
sData->result = -1;
}
// Defines an array of char pointer with the dimension of the number of tokens
sData->result = tc;
char *tokens[tc];
// Resets the token engine
strcpy(data,source);
// Strip out the first token found
token = strtok(data, delimiter);
tokens[0] = token;
tc = 0;
while (token != NULL)
{
// Strip out one token and store them into the token array
token = strtok(NULL, delimiter);
tc ;
tokens[tc] = token;
}
sData->tokens = tokens;
for(int i=0; i<sData->result; i ) {
printf("%s\n", sData->tokens[i]);
}
}
Result:
Part1
Part2
Part3
3 tokens found
(null)
(null)
(null)
Program ended with exit code: 0