• Welcome to Valhalla Legends Archive.
 

[C] String Problem [strtok()]

Started by Dyndrilliac, November 15, 2005, 02:40 PM

Previous topic - Next topic

Dyndrilliac

My program keeps crashing and I can't figure out for the life of me why.#include <vector.h>
#include <string.h>
#include <stdio.h>

typedef char*       LPTSTR;
typedef const char* LPCTSTR;

vector<LPTSTR> SplitString(LPTSTR szTextBuffer, LPCTSTR Delimiters);

int main() {
vector<LPTSTR> StringSet;
int i = 0;

StringSet = SplitString("Hi! My name is Matt!", " ");

for (i = 0; i < StringSet.size(); i++) {
printf("%s\n", StringSet[i]);
}

return 0;
}

vector<LPTSTR> SplitString(LPTSTR szTextBuffer, LPCTSTR Delimiters) {
vector<LPTSTR> Results;
LPTSTR szTempBuffer = strtok(szTextBuffer, Delimiters);

while (szTempBuffer != NULL) {
Results.push_back(szTempBuffer);
szTempBuffer = strtok(NULL, Delimiters);
}

return (Results);
}
It crashes on the line where 'szTempBuffer' is initialized at the top of the function definition of 'SplitString()'. All help on why this is happening and how to fix it is greatly appreciated.
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

Dyndrilliac

Well, I got it to *WORK* but I still don't know what's wrong with my original code...#include <vector.h>
#include <string.h>
#include <stdio.h>

typedef char*       LPTSTR;
typedef const char* LPCTSTR;

// Changed param 1 from char* to char[]
vector<LPTSTR> SplitString(char szTextBuffer[], LPCTSTR Delimiters);

int main() {
vector<LPTSTR> StringSet;
int i = 0;

char String[] = "Hi! My name is Matt!";
StringSet = SplitString(String, " ");

for (i = 0; i < StringSet.size(); i++) {
printf("%s\n", StringSet[i]);
}

return 0;
}

vector<LPTSTR> SplitString(char szTextBuffer[], LPCTSTR Delimiters) {
vector<LPTSTR> Results;
LPTSTR szTempBuffer = strtok(szTextBuffer, Delimiters);

while (szTempBuffer != NULL) {
Results.push_back(szTempBuffer);
szTempBuffer = strtok(NULL, Delimiters);
}

return (Results);
}
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

Kp

The bigger problem is what's wrong with your compiler.  It should never have permitted you to build that first example!  strtok writes into its first argument, but you were passing it a read-only string.  Of course it's going to crash when strtok tries to write into read-only memory.  The compiler should've warned you that you were passing a read-only argument to a function which (correctly!) warned you that it would be mutated.  There's also the more minor issue that your typedefs are wrong.  LPTSTR is a sequence of TCHARs, not of chars.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Dyndrilliac

I'm using Microsoft Visual C++ 6. Is there an option I should have enabled somewhere to raise the awareness of warnings/errors? Anyway, I found a similar explanation at another resource. So does this mean I can't pass a char* or I just can't pass a char* when I don't assign it a variable name?

Resource: http://gcc.gnu.org/ml/gcc-bugs/2001-04/msg00587.html
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

Kp

Quote from: Dyndrilliac on November 15, 2005, 08:59 PMI'm using Microsoft Visual C++ 6. Is there an option I should have enabled somewhere to raise the awareness of warnings/errors? Anyway, I found a similar explanation at another resource. So does this mean I can't pass a char* or I just can't pass a char* when I don't assign it a variable name?

Resource: http://gcc.gnu.org/ml/gcc-bugs/2001-04/msg00587.html

Passing a char* is fine.  You were passing a const char*, which is not fine.  That your compiler didn't warn you about this mistake speaks of a bug or a misconfiguration in the compiler.  In gcc, you'd get the warning if you turn on all the useful warnings.  I don't recall how to do it in VC++6 -- it's been a long time since I had to deal with that mess of a tool, and I'm glad to be done with it. :)
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Dyndrilliac

Well, My warning level is 4 and I have it set to treat warnings as errors.

Also, it isn't letting me pass a char* either. I replaced char String[] = "Hi! My name is Matt!"; with this:LPSTR String = "Hi! My name is Matt!"; And it still crashed. I changed my typedefs to:typedef char* LPSTR;
typedef const char* LPCSTR;
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

Adron

The point is that "Hi! My name is Matt!" is a read-only string. You cannot pass in a pointer to a read-only string; you need a pointer to a read-write string.

Eibro

Hi, this might be of some interest to you:
http://cs.stmarys.ca/~e_brooks/strtok.cpp
A robust splitting function, along the same lines as you have used.
You could improve on it by templating it to take std::basic_string< char > or std::basic_string< wchar_t >.
Eibro of Yeti Lovers.

Joe[x86]

QuoteThe bigger problem is what's wrong with your compiler. It should never have permitted you to build that first example!
QuoteI'm using Microsoft Visual C++ 6.

Am I not the only one who found that insanely funny?
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

UserLoser.

Quote from: Joe on November 20, 2005, 01:44 PM
QuoteThe bigger problem is what's wrong with your compiler. It should never have permitted you to build that first example!
QuoteI'm using Microsoft Visual C++ 6.

Am I not the only one who found that insanely funny?

What's so funny?