473,606 Members | 2,409 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

strtok ( ) help

ern
I'm using strtok( ) to capture lines of input. After I call
"splitComma nd", I call strtok( ) again to get the next line. Strtok( )
returns NULL (but there is more in the file...). That didn't happen
before 'splitCommands' entered the picture. The problem is in
splitCommands( ) somehow modifying the pointer, but I HAVE to call that
function. Is there a way to make a copy of it or something ?

/* HERE IS MY CODE */

char * lineOfScript;
const char * delim = "\n";

lineOfScript = strstr(scriptFi leBuffer,":prep rocess:"); //find starting
place in script
lineOfScript = strtok(lineOfSc ript,delim); //skip a line
lineOfScript = strtok(NULL,del im); //get next line... now I have a
command
splitCommand(li neOfScript); //this is probably where my pointer gets
messed up...
lineOfScript = strtok(NULL,del im); //get next line, but strtok returns
NULL

//Split up command into seperate words.
//Store words in global array
int splitCommand(ch ar * command){
const char * delimeters = " ";
int i = 0;
g_UserCommands[0] = strtok(command, " ");
while(g_UserCom mands[i] != NULL && i < 5){
//printf("%s", g_UserCommands[i]);//for debugging...
i+=1;
g_UserCommands[i] = strtok(NULL, " ");
}
i=0;
return 1;
}

Jan 20 '06 #1
13 4914
ern wrote:
I'm using strtok( ) to capture lines of input. After I call
"splitComma nd", I call strtok( ) again to get the next line. Strtok( )
returns NULL (but there is more in the file...). That didn't happen
before 'splitCommands' entered the picture. The problem is in
splitCommands( ) somehow modifying the pointer, but I HAVE to call that
function. Is there a way to make a copy of it or something ?

/* HERE IS MY CODE */

char * lineOfScript;
const char * delim = "\n";

lineOfScript = strstr(scriptFi leBuffer,":prep rocess:"); //find starting
place in script
lineOfScript = strtok(lineOfSc ript,delim); //skip a line
lineOfScript = strtok(NULL,del im); //get next line... now I have a
command
splitCommand(li neOfScript); //this is probably where my pointer gets
messed up...
lineOfScript = strtok(NULL,del im); //get next line, but strtok returns
NULL

//Split up command into seperate words.
//Store words in global array
int splitCommand(ch ar * command){
const char * delimeters = " ";
int i = 0;
g_UserCommands[0] = strtok(command, " ");
while(g_UserCom mands[i] != NULL && i < 5){
//printf("%s", g_UserCommands[i]);//for debugging...
i+=1;
g_UserCommands[i] = strtok(NULL, " ");
}
i=0;
return 1;
}


In splitCommand() you start a new strtok() "session", so when
you return and invoke it next it actually searches from where it
left off in 'command'. This was a local variable to
splitCommand(), and there's no telling what's there once
splitCommand() returns (it actually /is not/ there anymore).

C passes /all/ parameters by value (even pointers), i.e. a copy
is made for the called function. After the function returns the
object ceases to exist. Trying to access it invokes Undefined
Behaviour.

Cheers

Vladimir
--
My e-mail address is real, and I read it.
Jan 20 '06 #2
Vladimir S. Oka wrote:
ern wrote:
I'm using strtok( ) to capture lines of input. After I call
"splitComma nd", I call strtok( ) again to get the next line. Strtok( )
returns NULL (but there is more in the file...). That didn't happen
before 'splitCommands' entered the picture. The problem is in
splitCommands( ) somehow modifying the pointer, but I HAVE to call that
function. Is there a way to make a copy of it or something ?

/* HERE IS MY CODE */

char * lineOfScript;
const char * delim = "\n";

lineOfScript = strstr(scriptFi leBuffer,":prep rocess:"); //find starting
place in script
lineOfScript = strtok(lineOfSc ript,delim); //skip a line
lineOfScript = strtok(NULL,del im); //get next line... now I have a
command
splitCommand(li neOfScript); //this is probably where my pointer gets
messed up...
lineOfScript = strtok(NULL,del im); //get next line, but strtok returns
NULL

//Split up command into seperate words.
//Store words in global array
int splitCommand(ch ar * command){
const char * delimeters = " ";
int i = 0;
g_UserCommands[0] = strtok(command, " ");
while(g_UserCom mands[i] != NULL && i < 5){
//printf("%s", g_UserCommands[i]);//for debugging...
i+=1;
g_UserCommands[i] = strtok(NULL, " ");
}
i=0;
return 1;
}


In splitCommand() you start a new strtok() "session", so when you return
and invoke it next it actually searches from where it left off in
'command'. This was a local variable to splitCommand(), and there's no
telling what's there once splitCommand() returns (it actually /is not/
there anymore).


Consult your system help/manuals for a detailed description of
how strtok() works. The C Standard describes it in 7.21.5.8.
I've last used it too long ago to dare paraphrase either.

Cheers

Vladimir

--
My e-mail address is real, and I read it.
Jan 20 '06 #3
ern wrote:
I'm using strtok( ) to capture lines of input. After I call
"splitComma nd", I call strtok( ) again to get the next line. Strtok(
) returns NULL (but there is more in the file...). That didn't happen
before 'splitCommands' entered the picture. The problem is in
splitCommands( ) somehow modifying the pointer, but I HAVE to call
that function. Is there a way to make a copy of it or something ?

/* HERE IS MY CODE */

char * lineOfScript;
const char * delim = "\n";

lineOfScript = strstr(scriptFi leBuffer,":prep rocess:"); //find
starting place in script
lineOfScript = strtok(lineOfSc ript,delim); //skip a line
lineOfScript = strtok(NULL,del im); //get next line... now I have a
command
splitCommand(li neOfScript); //this is probably where my pointer gets
messed up...
lineOfScript = strtok(NULL,del im); //get next line, but strtok
returns NULL

//Split up command into seperate words.
//Store words in global array
int splitCommand(ch ar * command){
const char * delimeters = " ";
int i = 0;
g_UserCommands[0] = strtok(command, " ");
while(g_UserCom mands[i] != NULL && i < 5){
//printf("%s", g_UserCommands[i]);//for debugging...
i+=1;
g_UserCommands[i] = strtok(NULL, " ");
}
i=0;
return 1;
}


strtok(lineOfSc ript,delim);

After the initial call, strtok() has to 'remember' the data you've asked it
to parse. To do that here, it makes a copy of whatever lineOfScript pointed
to, and stores it in some internal buffer [that it maintains, and you can't
directly access].
strtok(NULL,del im);

When you call it again, passing NULL as the first param, it simply continues
parsing from wherever it previously left off - i.e., it continues to parse
its internal buffer as set by whatever lineOfScript originally pointed to.
strtok("BOO",de lim);

Now, if you call it again with a non-NULL initial param, it forgets whatever
data it was previously storing/working on and resets its internal buffer to
whatever data you've just passed in - a copy of "BOO" in this case. So,
whatever you didn't yet parse - that was originally ref'ed by lineOfScript -
is now lost and forgotten.

Bottom line, you can't do what you're trying to do with ...

p = strtok(p1, p2);

while(strtok(NU LL, p2))
{
p3 = strtok(p4, ...);

...
}
--
=============== =============== =============== =============== ===
In an attempt to reduce 'unwanted noise' on the 'signal' ...

Disclaimer:

Any comment/code I contribute might =NOT= be 100% portable, nor
semantically correct [read - 'not 100% pedantically correct'].
I don't care too much about that though, and I reckon it's the
same with most 'visitors' here. However, rest assured that any
'essential' (?) corrections WILL almost certainly appear v.soon
[read - 'to add noise as they see fit, a pedant will be along
shortly'].

WARNINGS: Always read the label. No beside-the-point minutiae
filter supplied. Keep away from children. Do not ignite.
=============== =============== =============== =============== ===
Jan 20 '06 #4
pemo wrote:

strtok(lineOfSc ript,delim);

After the initial call, strtok() has to 'remember' the data you've
asked it to parse. To do that here, it makes a copy of whatever
lineOfScript pointed to, and stores it in some internal buffer [that
it maintains, and you can't directly access].


That's not likely. What it will "remember" is the last pointer value
that it returned, which is an offset into the string (probably just a
static char*. If it made a copy of the string, not only would that be
inefficient, but if an operation changed the original string between
calls to strtok() its copy would no longer match.

Brian
Jan 20 '06 #5
Default User wrote:
pemo wrote:

strtok(lineOfSc ript,delim);

After the initial call, strtok() has to 'remember' the data you've
asked it to parse. To do that here, it makes a copy of whatever
lineOfScript pointed to, and stores it in some internal buffer [that
it maintains, and you can't directly access].


That's not likely. What it will "remember" is the last pointer value
that it returned, which is an offset into the string (probably just a
static char*. If it made a copy of the string, not only would that be
inefficient, but if an operation changed the original string between
calls to strtok() its copy would no longer match.


Yes, you're probably right, thanks for the correction ... hold on, brb <time
passes> ...
....
yup, certainly looks like it *is* as you say - for the gcc version at least.
Still, makes one wonder whether your comment ["but if an operation changed
the original string between calls to strtok() its copy would no longer
match"] might either be useful, or else goes against how the docs say
strtok() works.

int main(void)
{
char ar[] = "now is the time for all good men to come to the aid of the
party";

char * p = NULL;

int n = 0;

p = strtok(ar, " ");

while(p != NULL)
{
puts(p);

++n;

if(n % 5 == 0)
{
strcpy(ar, "the quick brown fox jumps over the lazy dog");
}

p = strtok(NULL, " ");
}
}
now
is
the
time
for
jumps
over
the
lazy
dog
--
=============== =============== =============== =============== ===
In an attempt to reduce ‘unwanted noise’ on the ‘signal’ ...

Disclaimer:

Any comment/code I contribute might =NOT= be 100% portable, nor
semantically correct [read - ‘not 100% pedantically correct’].
I don’t care too much about that though, and I reckon it’s the
same with most ‘visitors’ here. However, rest assured that any
‘essential’ (?) corrections WILL almost certainly appear v.soon
[read - ‘to add noise as they see fit, a pedant will be along
shortly’].

WARNINGS: Always read the label. No beside-the-point minutiae
filter supplied. Keep away from children. Do not ignite.
=============== =============== =============== =============== ===
Jan 20 '06 #6
pemo wrote:
Default User wrote:

That's not likely. What it will "remember" is the last pointer value
that it returned, which is an offset into the string (probably just
a static char*. If it made a copy of the string, not only would
that be inefficient, but if an operation changed the original
string between calls to strtok() its copy would no longer match.


Yes, you're probably right, thanks for the correction ... hold on,
brb <time passes> ... ...
yup, certainly looks like it is as you say - for the gcc version at
least. Still, makes one wonder whether your comment ["but if an
operation changed the original string between calls to strtok() its
copy would no longer match"] might either be useful, or else goes
against how the docs say strtok() works.

Remember also that strtok() has to modify the original string, so it
has to have a pointer into that string in all cases. That is, it
doesn't help to work on copy of the string because it has to punch null
characters in place of the delimiters. Also, the return value is a
pointer into the original string (or NULL of course).

The strtok() syntax and semantics are well into the "cheap, fast, and
dirty" style.

Brian
Jan 20 '06 #7
Default User wrote:
pemo wrote:
Default User wrote:
That's not likely. What it will "remember" is the last pointer value
that it returned, which is an offset into the string (probably just
a static char*. If it made a copy of the string, not only would
that be inefficient, but if an operation changed the original
string between calls to strtok() its copy would no longer match.


Yes, you're probably right, thanks for the correction ... hold on,
brb <time passes> ... ...
yup, certainly looks like it is as you say - for the gcc version at
least. Still, makes one wonder whether your comment ["but if an
operation changed the original string between calls to strtok() its
copy would no longer match"] might either be useful, or else goes
against how the docs say strtok() works.

Remember also that strtok() has to modify the original string, so it
has to have a pointer into that string in all cases. That is, it
doesn't help to work on copy of the string because it has to punch
null characters in place of the delimiters. ...

The strtok() syntax and semantics are well into the "cheap, fast, and
dirty" style.
Yup, ok, and I guess, from 7.21.5.8.2 "A sequence of calls to the strtok
function breaks *the string pointed to by s1* into a ..." [pretty much]
implies that a copy should *not* be made [hmmmm ????]. Whether it really
*is certain though* ... if this [the std] were a law!

Ok, I reckon the meaning *is clear* [gulp] in this case.
Also, the return value is a pointer into the original string (or NULL of
course).


Jeez, I really want to be the last one to want to play *the pedantic card on
c.l.c* (surely, c.std.c is where *certain types* should 'go play'), but the
std says ...
The strtok function returns a pointer to the first character of a token,
or a null pointer if there is no token.


Now, it's late [here] and I've not bothered to parse *all* the previous
paras in the std to see if there's a case for categorically stating that
'token', in this context, *is* necessaraily a member of the set of things in
the set of inputs to strtok(). But, if there's not a case, then "returns a
pointer to the first character of a token" doesn't, I think, preclude strtok
returning a pointer into some local [or any other] buffer, rather than the
one encoding the original string [the input] ... just that [perhaps], at the
time, the semantics of what token it is pointing to tallys with what its
input is?

As to the answer to this ... I actually don't give much of a damn [*a fuck*
actually], I'm more of a computational linguist these days, and it's *the
language* that interests me mostly now [my X3J11 days are a distant
memory] - and how, something that often appears at first sight reasonably
clear, can, in actual fact, be anything but! However, I'd rather ... than
be a pedant about it all now.
--
=============== =============== =============== =============== ===
In an attempt to reduce ‘unwanted noise’ on the ‘signal’ ...

Disclaimer:

Any comment/code I contribute might =NOT= be 100% portable, nor
semantically correct [read - ‘not 100% pedantically correct’].
I don’t care too much about that though, and I reckon it’s the
same with most ‘visitors’ here. However, rest assured that any
‘essential’ (?) corrections WILL almost certainly appear v.soon
[read - ‘to add noise as they see fit, a pedant will be along
shortly’].

WARNINGS: Always read the label. No beside-the-point minutiae
filter supplied. Keep away from children. Do not ignite.
=============== =============== =============== =============== ===
Jan 21 '06 #8
pemo wrote:

Now, it's late [here] and I've not bothered to parse all the previous
paras in the std to see if there's a case for categorically stating
that 'token', in this context, is necessaraily a member of the set of
things in the set of inputs to strtok(). But, if there's not a case,
then "returns a pointer to the first character of a token" doesn't, I
think, preclude strtok returning a pointer into some local [or any
other] buffer, rather than the one encoding the original string [the
input] ... just that [perhaps], at the time, the semantics of what
token it is pointing to tallys with what its input is?


What's unclear about this?

A sequence of calls to the strtok function breaks the
string pointed to by s1 into a sequence of tokens, each of
which is delimited by a character from the string pointed to
by s2.

"Breaks the string". Not forms some copies. Read how tokens are found
and formed. It pretty well lays out the state machine for you.


Brian
Jan 21 '06 #9
Default User wrote:
pemo wrote:

Now, it's late [here] and I've not bothered to parse all the previous
paras in the std to see if there's a case for categorically stating
that 'token', in this context, is necessaraily a member of the set of
things in the set of inputs to strtok(). But, if there's not a case,
then "returns a pointer to the first character of a token" doesn't, I
think, preclude strtok returning a pointer into some local [or any
other] buffer, rather than the one encoding the original string [the
input] ... just that [perhaps], at the time, the semantics of what
token it is pointing to tallys with what its input is?


What's unclear about this?

A sequence of calls to the strtok function breaks the
string pointed to by s1 into a sequence of tokens, each of
which is delimited by a character from the string pointed to
by s2.

"Breaks the string". Not forms some copies. Read how tokens are found
and formed. It pretty well lays out the state machine for you.


Ho && Hum

--
=============== =============== =============== =============== ===
In an attempt to reduce ‘unwanted noise’ on the ‘signal’ ...

Disclaimer:

Any comment/code I contribute might =NOT= be 100% portable, nor
semantically correct [read - ‘not 100% pedantically correct’].
I don’t care too much about that though, and I reckon it’s the
same with most ‘visitors’ here. However, rest assured that any
‘essential’ (?) corrections WILL almost certainly appear v.soon
[read - ‘to add noise as they see fit, *a pedant* will be along
shortly’].

WARNINGS: Always read the label. No beside-the-point minutiae
filter supplied. Keep away from children. Do not ignite.
=============== =============== =============== =============== ===
Jan 21 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
414
by: Ram Laxman | last post by:
Hi all, I have written the following code: /* strtok example */ #include <stdio.h> #include <string.h> static const char * const resultFileName = "param.txt";
8
2236
by: manochavishal | last post by:
Hi I am writing a Program in which i get input as #C1012,S,A#C1013,S,U I want to get C1012,S,A using strtok and then pass this to function CreateVideo which will further strtok this (C1012,S,A) and store the required values.
2
2081
by: manochavishal | last post by:
Hi I am writing a Program in which i get input as #C1012,S,A#C1013,S,U I want to get C1012,S,A using strtok and then pass this to function CreateCopies which will further strtok this (C1012,S,A) and store the required
8
1921
by: hu | last post by:
hi, everybody! I'm testing the fuction of strtok(). The environment is WinXP, VC++6.0. Program is simple, but mistake is confusing. First, the below code can get right outcome:"ello world, hello dreams." #include <stdafx.h> #include <string.h> #include <stdio.h> int main()
4
2724
by: Michael | last post by:
Hi, I have a proble I don't understand when using strtok(). It seems that if I make a call to strtok(), then make a call to another function that also makes use of strtok(), the original call is somehow confused or upset. I have the following code, which I am using to tokenise some input which is in th form x:y:1.2: int tokenize_input(Sale *sale, char *string){
5
25797
by: Kelly B | last post by:
I need a function which returns me a "word" from a given string and then sets the pointer to the next one which is then retrieved during further calls to the function. I think strtok( ) is the solution but i could not understand the use of the function as given in the C99 standard EXAMPLE #include <string.h> static char str = "?a???b,,,#c";
29
2563
by: Pietro Cerutti | last post by:
Hello, here I have a strange problem with a real simple strtok example. The program is as follows: ### BEGIN STRTOK ### #include <string.h> #include <stdio.h>
1
1341
schmals
by: schmals | last post by:
Hi, I am writing a UNIX shell program and have encountered a problem that I have spent way too many hours trying to solve to no avail. I have narrowed down my problem concisely and made a easier to follow test program that has the same problem in it. Here is the code for the sample program: char string = "hello my name is Scott"; char* word; char** sargv; int arg_count = 0; int i;
11
17165
by: magicman | last post by:
can anyone point me out to its implementation in C before I roll my own. thx
0
8440
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8096
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8306
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6773
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
5966
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
3937
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
3980
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2448
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1557
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.