Reputation: 11
I'm wanting to use the strtok() function to parse a string, and I'd like to create a copy of the values in the tokens returned (as I gather that the tokens returned from this function are pointers).
Essentially, my AIM is to create a pointer which points to an array of strings, which hold copies of the values at the address of each token. My code attempting this so far (And failing) is below: (Also I want the tokens to be able to hold enough space for three characters).
(NOTE I'm not interested in changing my method of how to split a string - and I'm aware there are disadvantages to strtok)
char words[] = "red, dry, wet, gut"; // this is the input string
char* words_split[100];
char token[3]; // creates space for a token to hold up to 3 characters (?)
int count = 0;
char* k = strtok(words, ","); // the naming of k here is arbitrary
while (k != NULL) {
k = strtok(NULL, ",");
token[0] = *k; // I'm aware the 0 here is wrong, but I don't know what it should be
words_split[count] = token;
count++;
}
And then I'd like to be able to access each of the individual elements, i.e. red, from words_split.
Upvotes: 1
Views: 2622
Reputation: 126
This is basically a makeover version of mnistic's answer. Adding just in case it might help you.
#include <bits/stdc++.h>
using namespace std;
int main()
{
char sentence[] = "red, dry, wet, gut"; // this is the input string
vector<char *> words;
for(char *token=strtok(sentence,","); token != NULL; token=strtok(NULL, ","))
{
const int wordLength = strlen(token) + 1;
char *word = new char [wordLength];
strcpy(word, token);
words.push_back(word);
cout << "\nWord = " << word;
}
// cleanup
for(int i=0; i<words.size(); i++)
{
delete[] words[i];
}
return 0;
}
Upvotes: 0
Reputation: 781096
You don't need the token
variable. Your code is setting every element of words_split
to point to the same token, which will end up being just the last token in the string.
Just store the addresses returned by strtok
:
int count = 0;
k = strtok(words, ",");
while (k) {
words_split[count++] = k;
}
If you need to make copies, you can use the strdup()
function:
words_split[count++] = strdup(k);
This is a POSIX function, not standard C++. See usage of strdup for an implementation if you need it.
Or use std::string
instead of C strings, as in mnistic's answer.
Upvotes: 0
Reputation: 11020
Since you are using C++, just use a vector to hold the strings:
char words[] = "red, dry, wet, gut"; // this is the input string
std::vector<std::string> strs;
char* k;
for (k = strtok(words, " ,"); k != NULL; k = strtok(NULL, " ,")) {
strs.push_back(k);
}
for(auto s : strs)
{
std::cout << s << std::endl;
}
If you need to access the raw pointer from a string stored in the vector, just do s.c_str()
.
Upvotes: 2