473,805 Members | 2,030 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

strtok and strtok_r

Dear experts,

As I know strtok_r is re-entrant version of strtok.
strtok_r() is called with s1(lets say) as its first parameter.
Remaining tokens from s1 are obtained by calling strtok_r() with a
null pointer for the first parameter.
My confusion is that this behavior is same as strtok. So I assume
strtok_r must also be using any function static variable to keep the
information about s1. If this is the case then how strtok_r is re-
entrant?
Otherwise how it keeps the information about s1?

Regards,
Siddharth

Sep 14 '07
75 25148
"Ben Bacarisse" <be********@bsb .me.ukschrieb im Newsbeitrag
news:87******** ****@bsb.me.uk. ..
CBFalconer <cb********@yah oo.comwrites:
>Joachim Schmitz wrote:
>>"Joachim Schmitz" <no*********@sc hmitz-digital.deschri eb:
"Joe Wright" <jo********@com cast.netschrieb :
... snip ...
>>>>>
size_t strlen(const char *s) {
size_t r = 0;
if (s) while (*s++) ++r;
return r;
}

Well, that version of strlen doesn't distinguish between a NULL
and an empty string. This would:
size_t strlen(const char *s) {
size_t r = (size_t)-1;
if (s) while (*s++) ++r;
return ++r;
}

Nonsense, thinko...
if (s) { r=0; while (*s++) ++r; }
return r;
or simpler
size_t strlen(const char *s) {
size_t r = 0;
if (s) while (*s++) ++r;
else r = (size_t)-1; /* and possibly set errno, e.g. to EINVAL */
return r;
}

If you bother to stop and think about it, I think you will see that
all four routines do the same thing.

Nope. The third and fourth correctly implement the specification
given for the second (which simply re-implements the behaviour of
the first).
I was quite surprised that my mistake went undetected for a day...
Sep 18 '07 #71
CBFalconer <cb********@yah oo.comwrites:
Ben Bacarisse wrote:
>James Antill <ja***********@ and.orgwrites:
... snip ...
>>>
Are you sure you weren't arguing about:

strcpy(dst, src);
vs.
memcpy(dst, src, strlen(src) + 1);

...as I find it hard to believe that Richard was arguing that
strcpy would be faster (possibly on certain platforms it's very
close, but not faster).

I was surprised to find it was. I decided to write a small test,
and for short strings, strdup written with strcpy is faster than
strdup written with memcpy (they both use strlen first to find
out how much to copy). The cut-off point on my laptop is at 164
bytes without any optimisation. With -O2 the cutoff goes down
to 16 bytes, but for small strings, strcpy seems faster. The
traditional YMMV seems to fall short of the mark here -- it
almost certainly will.

Just for fun, since you have the test code available, try comparing
it against the following small piece. Use the same optimization
levels etc.

char *dupstr(const char *s) {
char *p, *q;

if (p = q = malloc(1 + strlen(s)))
while (*p++ = *s++) continue;
return q;
} /* dupstr, untested */

which needs "#include <string.h>" and "#include <stdlib.h".
Without optimisation, worse than strcpy (as one would imagine). With
-O2 almost exactly the same as strcpy.

--
Ben.
Sep 18 '07 #72
Joachim Schmitz wrote:
"CBFalconer " <cb********@yah oo.comschrieb:
.... snip ...
>
>Well, I was only considering the standard strlen specification,
and returning zero for a NULL input (i.e. treating NULL as a zero
length string). I think. I totally missed the urge to return an
error indication for NULL input (which I don't consider aa good
idea, since using it requires non-std accepting code).

Hmm, but how is returning 0 for input NULL any better than
returning (site_t)-1? What else should be returned on a NULL
input? What else should happen instead?

assert(s==NULL) ;
<
is the only other sensible other option I see, as it assures the
program to aborts right there with a somewhat usefull error
message.
Remember, we are discussing an implementation of strlen. The
point, to me, is that an empty string (normally represented by a
pointer to '\0' char) can be equally well represented by NULL,
saving some memory. This is usable as long as the purpose of the
accessing code is to make or use a copy of the string. It fails
miserably if the idea is to modify the string, but in that case the
modifying code will be what blows up.

However, returning a value of "(size_t)-1" is hopeless. This
requires that every call to strlen be immediately followed by a
test of the result, and doesn't allow the (possible) minor
advantage of representing an empty string by NULL.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 19 '07 #73
CBFalconer <cb********@yah oo.comwrites:
[...]
Remember, we are discussing an implementation of strlen. The
point, to me, is that an empty string (normally represented by a
pointer to '\0' char) can be equally well represented by NULL,
saving some memory. This is usable as long as the purpose of the
accessing code is to make or use a copy of the string. It fails
miserably if the idea is to modify the string, but in that case the
modifying code will be what blows up.
[...]

No, an empty string cannot *equally* well be represented by a null
pointer, at least not in standard C. You can do that if you like, as
long as all the code that uses these strings specifically handles that
special case. But you can't use any of the standard functions that
take string arguments unless you wrap each call in a check for a null
pointer.

#include <stdio.h>
int main(void)
{
char *s = NULL;
printf("s = \"%s\"\n", s);
puts(s);
return 0;
}

On one implementation this prints:

s = "(null)"
Segmentation fault (core dumped)

Such an approach also makes it difficult to distinguish between an
empty string and a nonexistent string.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 19 '07 #74
Keith Thompson wrote:
CBFalconer <cb********@yah oo.comwrites:
[...]
>Remember, we are discussing an implementation of strlen. The
point, to me, is that an empty string (normally represented by a
pointer to '\0' char) can be equally well represented by NULL,
saving some memory. This is usable as long as the purpose of the
accessing code is to make or use a copy of the string. It fails
miserably if the idea is to modify the string, but in that case the
modifying code will be what blows up.
[...]

No, an empty string cannot *equally* well be represented by a null
pointer, at least not in standard C. You can do that if you like,
as long as all the code that uses these strings specifically
handles that special case. But you can't use any of the standard
functions that take string arguments unless you wrap each call in
a check for a null pointer.
Fair enough. I am guilty of unrestrained use of 'equally well', in
that I was only considering the programs actual use of such, and
ignoring the effect on other std procs.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 19 '07 #75
On 17 Sep, 21:00, Richard Heathfield <r...@see.sig.i nvalidwrote:

[...]
Kind of you, James, and I must admit I find it hard to imagine arguing that
way as well. Unfortunately, I remember that I had some pretty strange
misconceptions about C a decade or so ago, so it's not utterly impossible.
But no, I don't remember this particular debate. Your mod seems plausible,
however. (I can't think of any reason why I'd want to call memcpy in that
way, however.)
I found the thread, it was more than 7 years ago.. you gave me that
lesson. Posting the link to the thread, would be rather humiliating
for me, so I prefer not to! :)

Here is the function R.H. wrote back then:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char *dupstr(char *s)
{
char *t = NULL;
assert(s != NULL);
if(s != NULL) /* assert won't fire if NDEBUG is defined, so check
anyway */
{
t = malloc(strlen(s ) + 1); /* allocate enough bytes to make a
copy
of the string pointed to by s */
if(t != NULL) /* did it work? */
{
strcpy(t, s); /* perform the copy */
}
}
return t; /* returns NULL if the string could not be created */
}

and Ben Pfaff instantly suggested the "char *dupstr(const char *s)"
improvement.
Sep 19 '07 #76

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

Similar topics

23
3780
by: kbhat | last post by:
I had written some code using strtok_r for parsing strings with two "levels" of delimiters. The code was working like a charm, until it suddenly broke one day. You see, I was applying strtok on the input string itself, and as long as a variable string was passed to the function, everything was hunky dory. Then one day somebody decided to pass a constant string to my code ---- and everything came collapsing down like a domino. I...
6
476
by: gyan | last post by:
Hi How strtok track through string? char *strtok(char *s1, const char *s2); As i know The first call (with pointer s1 specified) returns a pointer to the first character of the first token, and will have written a null character into s1 immediately following the returned token. The function keeps track of its position in the string between separate calls, so that subsequent calls (which must be made with the first argument...
13
4931
by: ern | last post by:
I'm using strtok( ) to capture lines of input. After I call "splitCommand", 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 *...
33
1022
by: Geometer | last post by:
Hello, and good whatever daytime is at your place.. please can somebody tell me, what the standard behavior of strtok shall be, if it encounters two or more consecutive delimiters like in (checks omitted) char tst = "this\nis\n\nan\nempty\n\n\nline"; ^^^^ ^^^^^^ char *tok = strtok(tst, "\n");
18
3498
by: Robbie Hatley | last post by:
A couple of days ago I dedecided to force myself to really learn exactly what "strtok" does, and how to use it. I figured I'd just look it up in some book and that would be that. I figured wrong! Firstly, Bjarne Stroustrup's "The C++ Programming Language" said: (nothing)
4
2737
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){
14
3327
by: Mr John FO Evans | last post by:
I cam across an interesting limitation to the use of strtok. I have two strings on which I want strtok to operate. However since strtok has only one memory of the residual string I must complete one set of operations before starting on the second. This is inconvenient in the context of my program! So far the only solution I can see is to write a replacement for strtok to use on one of the strings. Can anyone offer an alternative?
3
441
by: siddhu | last post by:
Dear experts, As I know strtok_r is re-entrant version of strtok. strtok_r() is called with s1(lets say) as its first parameter. Remaining tokens from s1 are obtained by calling strtok_r() with a null pointer for the first parameter. My confusion is that this behavior is same as strtok. So I assume strtok_r must also be using any function static variable to keep the information about s1. If this is the case then how strtok_r is re-...
11
17180
by: magicman | last post by:
can anyone point me out to its implementation in C before I roll my own. thx
0
9716
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9596
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10609
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...
0
10360
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10105
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
9185
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...
0
6876
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5542
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...
2
3845
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.