Split string into substrings
-
Hello guys, I want to split a string into substrings using strtok(). The code is
#include "stdafx.h"
#using #include #include #include using namespace System;
using namespace std;char str2list(char* str, char** list, const char* delimiters)
{
for (char c = 0; c < sizeof(list) / sizeof(char*); c++)
{
list[c] = strtok(str, delimiters);
if (list[c] == NULL) break;
}
return c;
}int _tmain()
{
char** arglist;
arglist = new char*[16];
char* exmp = "I have a problem!";
str2list(exmp, arglist, " ");
for (char c = 0; c < sizeof(arglist) / sizeof(char*); c++)
{
cout << arglist[c] << endl;
}
delete[] arglist;
return 0;
}When I try to execute the program a runtime error occurs saying that there is a null-reference exception in the line
list[c] = strtok(str, delimiters);
. To ensure that there is enough free memory I even used thenew
operator. Does anyone have an idea why this doesn't work? Thanks and best wishes. -
Hello guys, I want to split a string into substrings using strtok(). The code is
#include "stdafx.h"
#using #include #include #include using namespace System;
using namespace std;char str2list(char* str, char** list, const char* delimiters)
{
for (char c = 0; c < sizeof(list) / sizeof(char*); c++)
{
list[c] = strtok(str, delimiters);
if (list[c] == NULL) break;
}
return c;
}int _tmain()
{
char** arglist;
arglist = new char*[16];
char* exmp = "I have a problem!";
str2list(exmp, arglist, " ");
for (char c = 0; c < sizeof(arglist) / sizeof(char*); c++)
{
cout << arglist[c] << endl;
}
delete[] arglist;
return 0;
}When I try to execute the program a runtime error occurs saying that there is a null-reference exception in the line
list[c] = strtok(str, delimiters);
. To ensure that there is enough free memory I even used thenew
operator. Does anyone have an idea why this doesn't work? Thanks and best wishes.Austrian_Programmer wrote:
When I try to execute the program a runtime error occurs saying that there is a null-reference exception in the line list[c] = strtok(str, delimiters);. To ensure that there is enough free memory I even used the new operator.
That's because (although
exmp
is achar*
), it's pointing at a string stored in read-only memory (string literals are read-only).strtok
needs to write to it. It can't, so you get a runtime exception. Changechar\* exmp = "I have a problem!";
to
char exmp\[\] = "I have a problem!";
and the crash goes away, because now you've allocated a read/write character array and initialised it from the (read-only) string literal. There are many other issues as well, however:
- Look at the
strtok
documentation[^] - you only pass instr
on the first call tostrtok
for that string - the rest of the time, you pass inNULL
. - The loop condition in
str2list
is all wrong.list
is achar**
, sosizeof(list)/sizeof(char*)
will be equal to 1. If you want to be safe with respect to the size oflist
, you need to explicitly pass it in - C/C++ doesn't pass around array sizes with arrays. - Similarly, the loop condition in _tmain is wrong (although this problem goes away if you take note of the next point).
- There's no point using
new
when you have a fixed array size - declaringarglist
withchar* arglist[16];
will work just as well. - I'm...interested that you use
char
as the type of the loop variables - Although the for loop in
str2list
may compile with the compiler you're using, it won't with VS2008 (and possibly won't with earlier compilers), and isn't compliant with the C++ standard - going by the standard, your loop variable isn't accessible outside the loop. - You return the number of tokens in the list from
str2list
...and then don't use it. Mmmmm.
Anyway - here's my fixed (I think) version of your code.
#include <iostream>
#include <string.h>using namespace std;
int str2list
- Look at the
-
Austrian_Programmer wrote:
When I try to execute the program a runtime error occurs saying that there is a null-reference exception in the line list[c] = strtok(str, delimiters);. To ensure that there is enough free memory I even used the new operator.
That's because (although
exmp
is achar*
), it's pointing at a string stored in read-only memory (string literals are read-only).strtok
needs to write to it. It can't, so you get a runtime exception. Changechar\* exmp = "I have a problem!";
to
char exmp\[\] = "I have a problem!";
and the crash goes away, because now you've allocated a read/write character array and initialised it from the (read-only) string literal. There are many other issues as well, however:
- Look at the
strtok
documentation[^] - you only pass instr
on the first call tostrtok
for that string - the rest of the time, you pass inNULL
. - The loop condition in
str2list
is all wrong.list
is achar**
, sosizeof(list)/sizeof(char*)
will be equal to 1. If you want to be safe with respect to the size oflist
, you need to explicitly pass it in - C/C++ doesn't pass around array sizes with arrays. - Similarly, the loop condition in _tmain is wrong (although this problem goes away if you take note of the next point).
- There's no point using
new
when you have a fixed array size - declaringarglist
withchar* arglist[16];
will work just as well. - I'm...interested that you use
char
as the type of the loop variables - Although the for loop in
str2list
may compile with the compiler you're using, it won't with VS2008 (and possibly won't with earlier compilers), and isn't compliant with the C++ standard - going by the standard, your loop variable isn't accessible outside the loop. - You return the number of tokens in the list from
str2list
...and then don't use it. Mmmmm.
Anyway - here's my fixed (I think) version of your code.
#include <iostream>
#include <string.h>using namespace std;
int str2list
Thanks for the answer. I've done a lot of microprocessor programming in the last time and there I use char whenever possible (it's the smallest type and working without causing any troubles). However, that's pure C and there are (I know) a few differences to C++. Normally I use C++ for game programming and mathematical things and that's more or less the first time I do something with strings in C++, so this is all in all just a try.
- Look at the
-
Thanks for the answer. I've done a lot of microprocessor programming in the last time and there I use char whenever possible (it's the smallest type and working without causing any troubles). However, that's pure C and there are (I know) a few differences to C++. Normally I use C++ for game programming and mathematical things and that's more or less the first time I do something with strings in C++, so this is all in all just a try.
Austrian_Programmer wrote:
Normally I use C++ for game programming and mathematical things and that's more or less the first time I do something with strings in C++, so this is all in all just a try.
That's cool - if you're starting out with C++ on a desktop platform, I really would recommend learning about the Standard Template Library - it makes (some) things a lot easier, especially managing strings and arrays (or vectors, which is the closest thing to an array in STL)..
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p