strtok - determine delimiter at certain position

M

magix

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.
 
R

Ralph Moritz

magix said:
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;
}
 
C

clayne

magix said:
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.
 
P

Peter Shaggy Haywood

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"?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Can't solve problems! please Help 0
strtok() 13
Why does strcat mess up the tokens in strtok (and strtok_r)? 92
strtok problem 16
strtok question 6
strtok 6
strtok problem 6
strtok problem 3

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top