Is there a function in C which can read dual delimiters,
there is strtok which works using a single delimiter.. Is

i need to decode a file as such

123#!45!2#!678#!666#!45!6#!

in the above case #! is the delimter, if i use strtok and use(#! as delimiter) 45!2 in the above data will get tokenized too, anybody has a solution?

No such library function:
it's not well-defined specification. For example, how about this delimiters set:

{ "!", "#", "#!" }

?
Elaborate non-contradictory specifications. It's not so hard to write a proper tokenizer in C...

My specification is to read a record with the delimiter "#!" which appears as a sequence, any other pattern should not be considered as delimiter. I will have to read in this record from a file and write to another file with ~ as delimiter

Input:
123#!45!2#!678#!666#!45!6#!

Output:
123~45!2~678~666~45!6~

/** Undestructive tokenizer. 
    @todo Add tsz < toksz test 
 */
const char* getTok(const char* s, char* tok, int toksz, const char* delim)
{
    if (s && *s) {
        int dlen = strlen(delim);
        const char* p = strstr(s,delim);
        int tsz = (p? p - s: strlen(s));
        if (tsz)
            memcpy(tok,s,tsz);
        tok[tsz] = '\0';
        return s + (p? tsz + dlen: tsz);
    }
    return 0;
}

int main()
{
    char tok[80];
    char str[] = "123#!45!2#!678#!666#!45!6#!";
    const char* p = str;
    while ((p = getTok(p,tok,sizeof tok,"#!")) != 0)
        printf("%s\n",tok);
    return 0;
}
Comments
solid

I think the following code help you to solve your problem.

char s1[100]="1123#!3344#!948#!20";
   char *p;
   int i=0;

   do
   {
     p=strtok(s1+i,"#!");
     i=i+strlen(p)+2;
     printf("\n%s",p);
     }while(p!=NULL);

Note: strtok is prototyped in string.h header file.

Comments
...

Consider also sscanf .

#include <stdio.h>

int main(void)
{
   const char line[] = "123#!45!2#!678#!666#!45!6#!";
   char text[10];
   int n;
   const char *ptr = line;
   while ( sscanf(ptr, "%9[^#]#!%n", text, &n) == 1 )
   {
      printf("%s~", text);
      ptr += n;
   }
   putchar('\n');
   return 0;
}

/* my output
123~45!2~678~666~45!6~
*/

Although as posted this will mishandle lone #'s within the text, such as "123#!45!2#!678#!6#66#!45!6#!" . It may give you some ideas, though.

This should help..

#include<stdio.h>

int main(void)
{
    char *str="123#!45!2#!678#!666#!45!6#!";
    char *temp1,*temp2;
    char *new_str;

    temp1=str;
    new_str=temp2;

    while(*temp1!='\0')
    {
        if(*temp1=='#' && *(temp1+1)=='!')
        {
            *temp2='~';
            temp2++;
            temp1+=2;
        }

        *temp2=*temp1;
        temp2++;
        temp1++;
    }

    *temp1='\0';

    while(*new_str!='\0')
    {
        printf("%c",*new_str);
        new_str++;
    }

    return 0;
}

Edited 3 Years Ago by Nick Evan: Fixed formatting

Comments
no

The above code looks good, But is it more efficient than using strstr or sscanf?

The above code looks good, But is it more efficient than using strstr or sscanf?

What's your efficiency criteria?
Is your application critically dependent on this tokenizing phase?
;)

yes it is.. performance matters as tokenizing is the crucial part of the application

yes it is.. performance matters as tokenizing is the crucial part of the application

Impossible!

Can you prove it? How many bytes per second is OK? What's i/o channels capacity?

Even if it's true: serious applications are never discussed on the forums like DaniWeb. True crucial parts of such applications are never assigned to programmers who can't tokenize a line with two-char delimiters ;)..

Comments
ROFLMAO!! Perfect, just perfect!

Buddy u seem to be in war mode.. I'm jus asking for suggestions..
I know you are an expert..

Comments
B-2 Hit! B-3 Sunk!
"war mode" haha

cool_zephyr>

while(*temp1!='\0')
{
if(*temp1=='#' && *(temp1+1)=='!')
{
*temp2='~';
temp2++;
temp1+=2;
}

Declaring a pointer doesn't magically set apart memory for you to manipulate, so you can not write or use what you don't have.

AIa>..so you can not write or use what you don't have.

Everybody knows the fact about declaring a pointer doesnot set memory. I want to know what happen when the following code is used.

char *str="Hello";

Everybody knows the fact about declaring a pointer doesnot set memory. I want to know what happen when the following code is used.

char *str="Hello";

An array containing the string literal "Hello" (including the null terminator) will exist somewhere; the contents of this array should be considered non-modifiable.

The pointer-to-char str will exist; it is initialized with the location of the first element of the array containing the string literal (that is, str will point to the beginning of the array).

See also http://c-faq.com/aryptr/aryptr2.html

adatapost> Everybody knows the fact about declaring a pointer doesnot set memory.

cool_zephyr didn't, and I don't want to think you haven't been paying much attention since you joined almost a year ago? This forum is full of instances of this recurring theme. Which nullifies your statement that "everybody knows"

adatapost> I want to know what happen when the following code is used. char *str="Hello";
Depends what you do to it. You are creating a read-only literal string, that can be accessed by the pointer str. You try to change it by overwriting it and you enter the undefined dimension.

I know you are an expert..

I missed this one. I am going to apply the "theory of relativity" to that sentence.

This article has been dead for over six months. Start a new discussion instead.