473,803 Members | 3,461 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

strtok() and EOL

Hi,

I'm using strtok() in the following way:

void obtain_param(ch ar *pmsg, CONF_PARAMS *cnf ) {
char *s1, *s2;
size_t msg_len;

s1 = strtok (pmsg,":");
if (s1) {
s2 = strtok (0, "");
msg_len = strcspn(s2, "\n");
if (memcmp(s1, "message", sizeof("message ")) == 0) {
cnf->msg_length = msg_len;
cnf->message = malloc(msg_len) ;
memcpy(cnf->message, s2, msg_len);
cnf->message[msg_len]='\0';

....

I extract the information from a configuration file. For some reason,
sometimes I get for msg_len 15 for this message:
message:thi s is a test


(when 'this is a test\n' is only 14 characters long, w/o the '\n')

In other installations (Linux) works just fine, but in my
Eclipse/CDT/cygwin sometimes is not.

Am I using strtok incorrectly? is the 's2' pointer messing things up?

Thanks,

F~
Nov 29 '05 #1
7 5710
On Tue, 29 Nov 2005 15:16:17 GMT, Fernando Barsoba
<fb******@veriz on.net> wrote in comp.lang.c:
Hi,

I'm using strtok() in the following way:

void obtain_param(ch ar *pmsg, CONF_PARAMS *cnf ) {
char *s1, *s2;
size_t msg_len;

s1 = strtok (pmsg,":");
if (s1) {
s2 = strtok (0, "");
msg_len = strcspn(s2, "\n");
if (memcmp(s1, "message", sizeof("message ")) == 0) {
cnf->msg_length = msg_len;
cnf->message = malloc(msg_len) ;
memcpy(cnf->message, s2, msg_len);
cnf->message[msg_len]='\0';

...

I extract the information from a configuration file. For some reason,
sometimes I get for msg_len 15 for this message:
>>message:thi s is a test


(when 'this is a test\n' is only 14 characters long, w/o the '\n')

In other installations (Linux) works just fine, but in my
Eclipse/CDT/cygwin sometimes is not.

Am I using strtok incorrectly? is the 's2' pointer messing things up?

Thanks,

F~


Where did the text string passed in 'pmsg' come from? Was it read
from a file? If it was read from a file, was the file opened in text
or binary mode? If you are reading a text file opened in binary mode
under Windows, you are getting the string as it appears in the file,
which would be:

"message:th is is a test\r\n"

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 29 '05 #2

"Fernando Barsoba" <fb******@veriz on.net> wrote in message
news:5h_if.6989 $6e5.1530@trndd c09...
Hi,

I'm using strtok() in the following way:

void obtain_param(ch ar *pmsg, CONF_PARAMS *cnf ) {
char *s1, *s2;
size_t msg_len;

s1 = strtok (pmsg,":");
if (s1) {
s2 = strtok (0, "");
msg_len = strcspn(s2, "\n");
if (memcmp(s1, "message", sizeof("message ")) == 0) {
cnf->msg_length = msg_len;
cnf->message = malloc(msg_len) ;
memcpy(cnf->message, s2, msg_len);
cnf->message[msg_len]='\0';

...

I extract the information from a configuration file. For some reason,
sometimes I get for msg_len 15 for this message:
message:thi s is a test


(when 'this is a test\n' is only 14 characters long, w/o the '\n')

In other installations (Linux) works just fine, but in my
Eclipse/CDT/cygwin sometimes is not.

Am I using strtok incorrectly? is the 's2' pointer messing things up?


Are you perhaps opening your file in binary mode? Note that
some OS's store newline as more than one character in text files.
E.g. Windows uses CR/LF pair and typical Windows C implementations
represent '\n' internally as LF (this would give the behavior
you describe if file were opened in binary mode on such systems
-- the 'extra' CR character would count as part of length returned
by 'strcspn()').

If you're not using it already, try text mode.

-Mike
Nov 29 '05 #3

Fernando Barsoba wrote:
Hi,

I'm using strtok() in the following way:
Probably fine, but you do know the issues with strtok, right?
In clc it is not re-entrant. In (OT) land, it is often not threadsafe
either. It is probably fine as you use it below.

void obtain_param(ch ar *pmsg, CONF_PARAMS *cnf ) {
char *s1, *s2;
size_t msg_len;

s1 = strtok (pmsg,":");
if (s1) {
s2 = strtok (0, "");
I'm not totally sure the empty string is legit here, perhaps others
can say. Works fine if you say ":" too.
msg_len = strcspn(s2, "\n");
if (memcmp(s1, "message", sizeof("message ")) == 0) {
Do you intend to compare the '\0' as you are? sizeof("message ") is 8.
Fine either way, strtok will have put one in.
cnf->msg_length = msg_len;
cnf->message = malloc(msg_len) ;
You don't allocate enough space here for the string including the '\0'
memcpy(cnf->message, s2, msg_len);
cnf->message[msg_len]='\0';
One byte overwrite here.

...

I extract the information from a configuration file. For some reason,
sometimes I get for msg_len 15 for this message:
>>message:thi s is a test


(when 'this is a test\n' is only 14 characters long, w/o the '\n')

In other installations (Linux) works just fine, but in my
Eclipse/CDT/cygwin sometimes is not.

Am I using strtok incorrectly? is the 's2' pointer messing things up?


I think you are using strtok mostly OK. I'd guess you are getting
messed up by DOS end of line vs unix here. Perhaps depends
on how the configuration file is read (binary vs text?).

-David

Nov 29 '05 #4
Fernando Barsoba <fb******@veriz on.net> writes:
I'm using strtok() in the following way:


I don't generally recommend using strtok(). It has at least
these problems:

* It merges adjacent delimiters. If you use a comma as
your delimiter, then "a,,b,c" is three tokens, not
four. This is often the wrong thing to do. In fact,
it is only the right thing to do, in my experience,
when the delimiter set is limited to white space.

* The identity of the delimiter is lost, because it is
changed to a null terminator.

* It modifies the string that it tokenizes. This is bad
because it forces you to make a copy of the string if
you want to use it later. It also means that you can't
tokenize a string literal with it; this is not
necessarily something you'd want to do all the time but
it is surprising.

* It can only be used once at a time. If a sequence of
strtok() calls is ongoing and another one is started,
the state of the first one is lost. This isn't a
problem for small programs but it is easy to lose track
of such things in hierarchies of nested functions in
large programs. In other words, strtok() breaks
encapsulation.

--
"You call this a *C* question? What the hell are you smoking?" --Kaz
Nov 29 '05 #5
Jack Klein wrote:
On Tue, 29 Nov 2005 15:16:17 GMT, Fernando Barsoba
<fb******@veriz on.net> wrote in comp.lang.c:
Hi,

I'm using strtok() in the following way:

void obtain_param(ch ar *pmsg, CONF_PARAMS *cnf ) {
char *s1, *s2;
size_t msg_len;

s1 = strtok (pmsg,":");
(...) Where did the text string passed in 'pmsg' come from? Was it read
from a file? If it was read from a file, was the file opened in text
or binary mode? If you are reading a text file opened in binary mode
under Windows, you are getting the string as it appears in the file,
which would be:

"message:th is is a test\r\n"

Thanks to all for your comments. Indeed, the string I'm getting is
"message:th is is a test\r\n". And 'pmsg' comes also from a file. Oddly
enough, I thought I opened the file in text mode. Here's the sequence of
calls:

fp = open_file(argv[1], "r");
cnf = get_param(fp);

-------------
CONF_PARAMS *get_param(FILE *f_param) {
....
p_msg = fgets(param, PARAM_LENGTH, f_param);
....
}
--------
FILE * open_file(char *file_name, char *foptions) {
FILE *fp;
if ((fp = fopen(file_name , foptions)) == NULL) {
printf("Can't open %s\n", file_name);
exit(1);
}
return fp;
}

As the comments pointed out, this seems to be a Windows issue. That's
why in Linux works fine. I'm not opening the file in binary mode though..

F~
Nov 29 '05 #6
Jack Klein wrote:
On Tue, 29 Nov 2005 15:16:17 GMT, Fernando Barsoba
<fb******@veriz on.net> wrote in comp.lang.c:


<snip>
>>message:thi s is a test


(when 'this is a test\n' is only 14 characters long, w/o the '\n')

In other installations (Linux) works just fine, but in my
Eclipse/CDT/cygwin sometimes is not.

Am I using strtok incorrectly? is the 's2' pointer messing things up?

Thanks,

F~


Where did the text string passed in 'pmsg' come from? Was it read
from a file? If it was read from a file, was the file opened in text
or binary mode? If you are reading a text file opened in binary mode
under Windows, you are getting the string as it appears in the file,
which would be:

"message:th is is a test\r\n"


Note that since Cygwin is emulating some of Unix it may think of \n as
being the line terminator rather than \r\n even when you open a stream
in text mode, so you could still get a spurious \r. For the intricacies
of Cygwin line termination you will have to ask on a Cygwin mailing
list, but if this is your problem one option is to check if the last
character of the line you read is \r and if so strip it.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 29 '05 #7
Fernando Barsoba wrote:
Jack Klein wrote:
On Tue, 29 Nov 2005 15:16:17 GMT, Fernando Barsoba
<fb******@veriz on.net> wrote in comp.lang.c:
<snip>
"message:th is is a test\r\n"
Thanks to all for your comments. Indeed, the string I'm getting is
"message:th is is a test\r\n". And 'pmsg' comes also from a file. Oddly
enough, I thought I opened the file in text mode. Here's the sequence of
calls:

fp = open_file(argv[1], "r");


Yes, that is opening in text mode.

<snip>
As the comments pointed out, this seems to be a Windows issue. That's
why in Linux works fine. I'm not opening the file in binary mode though..


See my previous post, it's a Cygwin issue. Specifically, Cygwin is
emulation Unix to a degree (that is its purpose) so by default it used
the Unix text file conventions. Ask on a Cygwin mailing list for the
details.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 29 '05 #8

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";
13
4930
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 *...
20
17246
by: bubunia2000 | last post by:
Hi all, I heard that strtok is not thread safe. So I want to write a sample program which will tokenize string without using strtok. Can I get a sample source code for the same. For exp: 0.0.0.0--->I want to tokenize the string using delimiter as as dot. Regards
8
1932
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
2736
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){
3
3811
by: nomad5000 | last post by:
Hi everybody! I'm having trouble using strtok to fill a matrix with int nrs. from a file. the code that is not working is the following: #include <iostream> #include <fstream> #include <string> #include <stdlib.h> using namespace std;
29
2591
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>
11
904
by: Lothar Behrens | last post by:
Hi, I have selected strtok to be used in my string replacement function. But I lost the last token, if there is one. This string would be replaced select "name", "vorname", "userid", "passwort" from "users" order by "users"
11
17180
by: magicman | last post by:
can anyone point me out to its implementation in C before I roll my own. thx
12
2362
by: Pilcrow | last post by:
Here is a quick program, together with its output, that illustrates what I consider to be a deficiency of the standard function strtok from <string.h>: I am using C:\>gcc --version gcc (GCC) 3.4.5 (mingw special) I would like there to be a default, to be returned when two delimiters
0
9703
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
9565
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
10550
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
10317
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
10069
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...
1
7604
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
6844
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
5501
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
5633
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.