By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,473 Members | 3,292 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,473 IT Pros & Developers. It's quick & easy.

strtok - determine delimiter at certain position

P: n/a
Dear Guru,

I have been thinking hard on how to token based on demiliter after certain
position.
Example, I have list of possible string below, and the the delimiter is "1"
with the rules below
- if the 5th character is "1", then it is delimiter
elseif the 7th character is "1", then it is delimiter
else
this string is not a valid string
NE341LCBAA35
NE311LCBAA35
NE141LCBAA35
NE31341LCBAA35

I have code:

strcpy(szPrefix,strtok(token,"1\n"));
strcpy(szSuffix,strtok(NULL,"1\n"));

but only able to detect the 1st occurence of "1", and treat it as delimiter,
based on the rules above, this is not valid if has string like NE311LCBAA35.

What I want to achieve is: If I have string NE311LCBAA35, my delimiter will
be the 5th "1", and my
szPrefix = "NE31"
szSuffix = "LCBAA35"

Could you share with me on how to achieve above rules ?

Many thanks.

P/S: this is not school homeworks or anything. I'm a working adult, just my
personal interest in programming.

Regards.


Sep 30 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
"magix" <ma***@asia.comwrites:
I have been thinking hard on how to token based on demiliter after certain
position.
Example, I have list of possible string below, and the the delimiter is "1"
with the rules below
- if the 5th character is "1", then it is delimiter
elseif the 7th character is "1", then it is delimiter
else
this string is not a valid string
For a simple case like this, just copying string segments around is
probably easier than trying to use strtok(). See my example program
below. (Error handling omitted for brevity)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
enum { MINDP = 4, MAXDP = 6 };
char *input, *prefix, *suffix;
size_t pos = 0;
size_t sl;

if (argc != 2) {
fprintf(stderr, "Usage: chop TEXT\n");
exit(1);
}

input = argv[1];
if (input[MINDP] == '1')
pos = MINDP;
else if (input[MAXDP] == '1')
pos = MAXDP;
else {
fprintf(stderr, "Error: invalid string\n");
exit(1);
}

sl = strlen(input) -pos -1;
prefix = malloc(sizeof(pos +1));
suffix = malloc(sl +1);
memcpy(prefix, input, pos);
memcpy(suffix, input +pos +1, sl);
prefix[pos] = suffix[sl] = '\0';

printf("Prefix: %s\nSuffix: %s\n", prefix, suffix);
return 0;
}

--
Ralph Moritz Ph: +27 846 269 070
GPG Public Key: http://ralphm.info/public.gpg

"Faith is believing something you know ain't true."
Sep 30 '06 #2

P: n/a
magix wrote:
Dear Guru,

P/S: this is not school homeworks or anything. I'm a working adult, just my
personal interest in programming.

Regards.
Yeah anyways, best to avoid strtok(), as it is a handicapped interface,
atleast in my opinion. For these types of routines, I typically just
use self-written stuff utilizing standard unix iovec structures
(although these are not necessarily required).

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#ifdef HAVE_UIO /* avoid comp.lang.c warnings */
#include <sys/uio.h>
#else
struct iovec {
void *iov_base;
size_t iov_len;
};
#endif

typedef struct iovec iov;

size_t iovtok(iov *v, size_t vc, const char *q, size_t sz, const char
*t, size_t tsz)
{
const char *p, *r;
size_t vct, tszt;

for (vct = 0, p = q, r = q + sz; vct < vc && q < r; q++) {
for (tszt = tsz; tszt; tszt--)
if (*q == t[tszt - 1]) break;

if (tszt == 0) {
continue;
} else if (q != p) {
v[vct].iov_base = (void *)p;
v[vct].iov_len = q - p;
vct++;
}

p = q + 1;
}

if (vct < vc && q != p) {
v[vct].iov_base = (void *)p;
v[vct].iov_len = q - p;
vct++;
}

return vct;
}

int main(int argc, char **argv)
{
char buf[1024];
size_t tl, c, vc, vct;
iov *v;

if (argc <= 2) return -1;
if ((vc = strtol(argv[1], 0, 10)) <= 0) return -1;
if ((v = malloc(sizeof(*v) * vc)) == NULL) return -1;

for (tl = strlen(argv[2]); fgets(buf, sizeof(buf), stdin); ) {
vct = iovtok(v, vc, buf, strlen(buf) - 1, argv[2], tl);

fprintf(stderr, "vct == %ld\n", (long)vct);
for (c = 0; c < vct; c++) {
fprintf(stderr,
"v[%ld].iov_len == %ld\n",
(long)c,
(long)v[c].iov_len);
fprintf(stderr,
"v[%ld].iov_base == \"%.*s\"\n",
(long)c,
(int)v[c].iov_len,
(char *)v[c].iov_base);
}
}

free(v);

return 0;
}
--

$ gcc -Wall -W -ansi -pedantic -g3 -o memsplt memsplt.c
$ ./memsplt.exe 10 "1" << EOF
NE341LCBAA35
NE311LCBAA35
NE141LCBAA35
NE31341LCBAA35
EOF
vct == 2
v[0].iov_len == 4
v[0].iov_base == "NE34"
v[1].iov_len == 7
v[1].iov_base == "LCBAA35"
vct == 2
v[0].iov_len == 3
v[0].iov_base == "NE3"
v[1].iov_len == 7
v[1].iov_base == "LCBAA35"
vct == 3
v[0].iov_len == 2
v[0].iov_base == "NE"
v[1].iov_len == 1
v[1].iov_base == "4"
v[2].iov_len == 7
v[2].iov_base == "LCBAA35"
vct == 3
v[0].iov_len == 3
v[0].iov_base == "NE3"
v[1].iov_len == 2
v[1].iov_base == "34"
v[2].iov_len == 7
v[2].iov_base == "LCBAA35"
I'm sure you can figure out the appropriate code logic to determine 5
vs 7, etc.

Sep 30 '06 #3

P: n/a
Groovy hepcat magix was jivin' on Sat, 30 Sep 2006 16:21:31 +0800 in
comp.lang.c.
strtok - determine delimiter at certain position's a cool scene! Dig
it!
>I have been thinking hard on how to token based on demiliter after certain
position.
Example, I have list of possible string below, and the the delimiter is "1"
with the rules below
- if the 5th character is "1", then it is delimiter
elseif the 7th character is "1", then it is delimiter
else
this string is not a valid string
That's incredibly simple.

if('1' == yer_string[4])
{
/* Delimiter is 5th character. */
}
else if('1' == yer_string[6])
{
/* Delimiter is 7th character. */
}
else
{
/* Invalid. */
}

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Oct 2 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.