Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

A C prog to do pattern searching 2

Status
Not open for further replies.

nevj

Technical User
Sep 21, 2002
14
US
I have to solve a problem for my wife who is engaged in Research in Breast Cancer.

1. She has frequently to search a list of alphabetic characters for an exact match of a pattern.
This pattern can be pasted into a file.Sometimes the characters are presented to her as a single line but other times as several columns which actually are intended to be a single line.
Also the case can vary.

e.g. mwaaagglwrsraglralfrsrdaalfpgcerglhcsavscknwlkkfasktkkkvwyespslgshstykpskleflmrstskktrkedharlralngllykaltdllctpevsqelydlnvelskvsltpdfsacraywkttlsaeqnahmeavlqrsaahmslisywqsqtldpgmkettlykmisgtlmphnpaapqsrpqapvcvgsimrrstsrlwstkggkikgsgawcgrgrwls

OR

mwaaagglwrsraglralfrsrdaalfpgc
erglhcsavscknwlkkfasktkkkvwyes
pslgshstykpskleflmrstskktrkedh
arlralngllykaltdllctpevsqelydl
nvelskvsltpdfsacraywkttlsaeqna
hmeavlqrsaahmslisywqsqtldpgmke
ttlykmisgtlmphnpaapqsrpqapvcvg
simrrstsrlwstkggkikgsgawcgrgrwls

OR

MWAAAGGLWRSRAGLRALFRSRDAALFPGC
ERGLHCSAVSCKNWLKKFASKTKKKVWYES
PSLGSHSTYPKSKLEFLMRSTSKKTRKEDH
ARLRALNGLLYKALTDLLCTPEVSQELYDL
NVELSKVSLTPDFSACRAYWKTTLSAEQNA
HMEAVLQRSAAHMSLISYWQSQTLDPGMKE
TTLYKMISGTLMPHNPAAPQSRPQAPVCVG
SIMRRSTSRLWSTKGGKIKGSGAWCGRGRWLS

OR

MWAAAGGLWRSRAGLRALFRSRDAALFPGCERGLHCSAVSCKNWLKKFASKTKKKVWYEPSLGSHSTYPKSKLEFLMRSTSKKTRKEDHARLRALNGLLYKALTDLLCTPEVSQELYDLNVELSKVSLTPDFSACRAYWKTTLSAEQNAHMEAVLQRSAAHMSLISYWQSQTLDPGMKETTLYKMISGTLMPHNPAAPQSRPQAPVCVGSIMRRSTSRLWSTKGGKIKGSGAWCGRGRWLS

2. There are ONLY two patterns to be searched for -


r?r??s
r?r??t

The ? can be any of the following characters

acdefghiklmnpqrstvxy

3. Once an exact match/s has been made it is essential to know the number of characters from the start of the line to each match.It is possible that there is more than one match.

Can anyone suggest a program in ANSI C that will compile in the first instance in Solaris (SunOS 5.9).

But is portable (source and then re compile) to HP-UX and AIX and to XP.

It is urgent.

Thanks
 
This is a simple minded one: not as fast as if you coded it as a state machine but it should be enough to get you started.

/*
String search
*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
/* Configurable items */
const char* user_pattern[] =
{
&quot;r?r??s&quot;,
&quot;r?r??r&quot;
};

#define BUFFER_MAX 1024
char data_buffer[BUFFER_MAX];
/********************************************************************/
struct Pattern
{
char* mPattern;
int mLength;
};
Pattern* pattern;
int pattern_max;

/********************************************************************
* Create upper and lowercase search patterns
********************************************************************/
void CreatePatterns ()
{
int p, u, s;
int user_pattern_max;

user_pattern_max = sizeof (user_pattern) / sizeof (user_pattern[0]);
pattern_max = user_pattern_max * 2;
pattern = (Pattern*) malloc (sizeof (Pattern) * pattern_max);

for (p = 0, u = 0; u < user_pattern_max; u++, p++)
{
int pattern_size;
char* upper;
pattern_size = strlen (user_pattern);
pattern[p].mLength = pattern_size;
pattern[p].mPattern = (char*) malloc (pattern_size + 1);

/* Lowercase version */
strcpy (pattern[p].mPattern, user_pattern);

/* Uppercase version */
p++;
upper = (char*) malloc (pattern_size + 1);
strcpy (upper, user_pattern);
for (s = 0; s < pattern_size; s++)
{
if (upper != '?')
upper = toupper (upper);
}
pattern[p].mLength = pattern_size;
pattern[p].mPattern = upper;
}
}

/*********************************************************************
* Search for a pattern in a line
*********************************************************************/
void Search (int iLine, char* iStr)
{
char* ch;
char* la; /* look ahead */
char* sch; /* search */
int p, s;

for (ch = iStr; *ch != '\0' && *ch != '\n'; ch++)
{
for (p = 0; p < pattern_max; p++)
{
sch = pattern[p].mPattern;
if (*ch == *sch)
{
la = ch;
for (s = 1; s < pattern[p].mLength; s++)
{
if (sch == '?') continue;
if (sch != la) break;
}
if (s == pattern[p].mLength)
{
/* Found */
printf (&quot;%d: %s\n&quot;, iLine, iStr);
return;
}
}
}
}
}

/*********************************************************************
* Check if we can continue. If we cannot, stop the program
*********************************************************************/
void FatalError (int iCondition, const char* iMessage, const char* iParam)
{
if (iCondition)
{
printf (iMessage, iParam);
exit (0);
}
}

/********************************************************************/
int main (int argc, const char* argv[])
{
FILE* data;
int line;
char* buffer;

#if 1
FatalError (argc < 2, &quot;Usage %s <datafile>\n&quot;, argv[0]);

data = fopen (argv[1], &quot;r&quot;);
FatalError (data == 0, &quot;Unable to open %s\n&quot;, argv[1]);
#else
/* Testing */
data = fopen (&quot;breast.txt&quot;, &quot;r&quot;);
#endif

CreatePatterns ();
for (line = 1; !feof (data); line++)
{
buffer = fgets (data_buffer, sizeof (data_buffer), data);
if (buffer)
{
Search (line, buffer);
}
}
fclose (data);
return 0;
}
 
fasta format on protein data?

anywho... there are c-libs for doing full blown pattern search in the *nixies.

have a look-see at the doc on...

#include <fnmatch.h>

I haven't gotten around to using it myself yet but it's on my to-do list.
 
Thanks for the info - I haven't been on the *nixes for a bit. I'll look it up when I'm next on one. Unfortunately, the OP said his wife wanted it on XP too.
 
Knowing the field *very* well I'd bet $$ to donuts that after nevj gives his proggie to Dr. Wife. She is going to say that base E can be replaced by base D here & just change for this & then for that replacement rule (because it's easy to replace some hydrophibic bases)... & the creatures would continue to feep...

wxb, For me, & I'm guessing you too, writing a regexp engine would be a lot of fun but it would take a while & Dr. Wife would start to question her husband's abilities if he started down that path. Go for the easy library kill & don't mess with writing too much on your own unless you're dead set against it.

Had a quick google for a windows lib... & got these...
Many others that I can't vouch for at all.

I'll likely get heckled for writing this here but this is one app where a scripting language might be more suited for the quick & dirty multi-platform programming in store for nevj. Sorry.
 
CluelessNewbie please enlighten me as to what *nixies is/are

You refer to it -
&quot;anywho... there are c-libs for doing full blown pattern search in the *nixies.&quot;

Thanks

 
Sorry, It's just my &quot;cute&quot; way of refering to any of the myraid forms of unix: Linux, FreeBSD, Solaris Unix, etc.

Fair warning: after a quick look-see for regular expression libraries in C it appears that the unix/*nixie world & the Windows world for regualr expression libraries are a bit different. So there will be annoying porting issues, likely minor but still there.

Sorry again for the confusion.

PS: I love C & don't want to turn anyone away from it but... what you're asking is bread & butter to bioinformatics programming... have you looked at or There are plenty of scripts & books explaining them for this sort of stuff. I tend to try & use the scripting languages for quick & dirty jobs like this & use C for the really big hairy jobs where I need the speed & control.

But that's just my opinion & note my handle! It's a truth in advertising kinda thing.
 
Matt,
BM is *THE* method to use if you're doing exact string matching. However, it starts to lose it's edge when there are wildcards. If you're into that kind of thing have a look at the &quot;agrep&quot; algo or the &quot;shift or&quot; method. both can be adapted for low numbers of mismatches (wild cards). Then gain, if you're doing regexps stick to the DFA & NDFA stuff... See the &quot;Red Dragon&quot; book for this stuff ad nauseum.
 
Hi xwb

Thought you might be interested

Tried on Solaris 5.9 - result below

$ cc -o eight eight.c
&quot;eight.c&quot;, line 23: undefined or not a type: Pattern
&quot;eight.c&quot;, line 23: syntax error before or at: *
&quot;eight.c&quot;, line 23: warning: old-style declaration or incorrect type for: patten
&quot;eight.c&quot;, line 36: syntax error before or at: )
&quot;eight.c&quot;, line 42: warning: argument #1 is incompatible with prototype:
prototype: pointer to const char : &quot;/usr/include/iso/string_iso.h&quot;, lin0
argument : pointer to pointer to const char
&quot;eight.c&quot;, line 43: warning: left operand of &quot;.&quot; must be struct/union object
&quot;eight.c&quot;, line 43: cannot access member of non-struct/union object
&quot;eight.c&quot;, line 44: warning: left operand of &quot;.&quot; must be struct/union object
&quot;eight.c&quot;, line 47: warning: left operand of &quot;.&quot; must be struct/union object
&quot;eight.c&quot;, line 47: warning: argument #2 is incompatible with prototype:
prototype: pointer to const char : &quot;/usr/include/iso/string_iso.h&quot;, lin6
argument : pointer to pointer to const char
&quot;eight.c&quot;, line 52: warning: argument #2 is incompatible with prototype:
prototype: pointer to const char : &quot;/usr/include/iso/string_iso.h&quot;, lin6
argument : pointer to pointer to const char
&quot;eight.c&quot;, line 55: warning: improper pointer/integer combination: op &quot;!=&quot;
&quot;eight.c&quot;, line 56: warning: improper pointer/integer combination: op &quot;=&quot;
&quot;eight.c&quot;, line 58: warning: left operand of &quot;.&quot; must be struct/union object
&quot;eight.c&quot;, line 58: cannot access member of non-struct/union object
&quot;eight.c&quot;, line 59: warning: left operand of &quot;.&quot; must be struct/union object
&quot;eight.c&quot;, line 61: cannot recover from previous errors
cc: acomp failed for eight.c


Tried again using gcc -

$ gcc -o eight eight.c eight.c:23: parse error before `*'
eight.c:23: warning: data definition has no type or storage class
eight.c: In function `CreatePatterns':
eight.c:36: `Pattern' undeclared (first use in this function)
eight.c:36: (Each undeclared identifier is reported only once
eight.c:36: for each function it appears in.)
eight.c:36: parse error before `)'
eight.c:42: warning: passing arg 1 of `strlen' from incompatible pointer type
eight.c:43: request for member `mLength' in something not a structure or union
eight.c:44: request for member `mPattern' in something not a structure or union
eight.c:47: request for member `mPattern' in something not a structure or union
eight.c:47: warning: passing arg 2 of `strcpy' from incompatible pointer type
eight.c:52: warning: passing arg 2 of `strcpy' from incompatible pointer type
eight.c:55: warning: comparison between pointer and integer
eight.c:56: warning: assignment makes pointer from integer without a cast
eight.c:58: request for member `mLength' in something not a structure or union
eight.c:59: request for member `mPattern' in something not a structure or union
eight.c: In function `Search':
eight.c:77: request for member `mPattern' in something not a structure or union
eight.c:81: request for member `mLength' in something not a structure or union
eight.c:83: warning: comparison between pointer and integer
eight.c:86: request for member `mLength' in something not a structure or union
 
My opinon may be a little skewed, since I started off as a C man and wandered into C++, VB, and Perl, and I have an unhealthy infatuation with the last one. It's been awhile since I've done anything in C, but wouldn't something like the following work?

char temp[6];

sscanf(source,&quot;r%[acdefghiklmnpqrstvxy]r%[acdefghiklmnpqrstvxy]%[acdefghiklmnpqrstvxy]t&quot;,temp);

Forgive me if my syntax has gone awry, but I thought you could define character classes in a scanf but enclosing them in [], negating it by leading the class with a ^. I can remember doing something like that at some point, but I think it was only a class of one character, is that its limit? It acts like a %s does, as needing a pointer to a char array.

Just a passing though. My official diagnosis: use Perl or anything that lets you put in a nice regular expression. A few *nix tools let you do that, I'm sure some of those have win32 ports. But like I said, I'm a little bias these days.
----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light
 
Oh, and this should compile...don't think I changed any meaning in it, just added a typdef and some subscripts.
Code:
/*
 *     String search
 *     */
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
/* Configurable items */
const char* user_pattern[] =
{
	    &quot;r?r??s&quot;,
	    &quot;r?r??r&quot;
};

#define BUFFER_MAX 1024
char data_buffer[BUFFER_MAX];
/********************************************************************/
typedef struct Pattern
{
	    char* mPattern;
            int mLength;
} Pattern; /* added typdef */

Pattern * pattern;
int pattern_max;

/********************************************************************
 * * Create upper and lowercase search patterns
 * ********************************************************************/
void CreatePatterns ()
{
    int p, u, s;
    int user_pattern_max;

    user_pattern_max = sizeof (user_pattern) / sizeof (user_pattern[0]);
    pattern_max = user_pattern_max * 2;
    pattern = (Pattern*) malloc (sizeof (Pattern) * pattern_max);
			        
    for (p = 0, u = 0; u < user_pattern_max; u++, p++)
    {
        int pattern_size;
	char* upper;
	pattern_size = strlen (user_pattern[u]);
	pattern[p].mLength = pattern_size;
	pattern[p].mPattern = (char*) malloc (pattern_size + 1);

	/* Lowercase version */
	strcpy (pattern[p].mPattern, user_pattern[u]);

	/* Uppercase version */
	p++;
	upper = (char*) malloc (pattern_size + 1);
	strcpy (upper, user_pattern[u]);
	for (s = 0; s < pattern_size; s++)
	{
	    if (upper[s] != '?')
	    upper[s] = toupper (upper[s]);
	}
	pattern[p].mLength = pattern_size;
	pattern[p].mPattern = upper;
    }
}

/*********************************************************************
 * * Search for a pattern in a line
 * *********************************************************************/
void Search (int iLine, char* iStr)
{
    char* ch;
    char* la;   /* look ahead */
    char* sch;  /* search */
    int p, s;

    for (ch = iStr; *ch != '\0' && *ch != '\n'; ch++)
    {
	for (p = 0; p < pattern_max; p++)
	{
	    sch = pattern[p].mPattern;
	    if (*ch == *sch)
	    {
		la = ch;
		for (s = 1; s < pattern[p].mLength; s++)
		{
		    if (sch[s] == '?') continue;
		    if (sch[s] != la[s]) break;
		}
		if (s == pattern[p].mLength)
		{
		    /* Found */
		    printf (&quot;%d: %s\n&quot;, iLine, iStr);
		    return;
		}
	    }
	}
    }
}

/*********************************************************************
 * * Check if we can continue.  If we cannot, stop the program
 * *********************************************************************/
void FatalError (int iCondition, const char* iMessage, const char* iParam)
{
    if (iCondition)
    {
	printf (iMessage, iParam);
	exit (0);
    }
}

/********************************************************************/
int main (int argc, const char* argv[])
{
    FILE* data;
    int line;
    char* buffer;

#if 1
    FatalError (argc < 2, &quot;Usage %s <datafile>\n&quot;, argv[0]);

    data = fopen (argv[1], &quot;r&quot;);
    FatalError (data == 0, &quot;Unable to open %s\n&quot;, argv[1]);
#else
    /* Testing */
    data = fopen (&quot;breast.txt&quot;, &quot;r&quot;);
#endif

    CreatePatterns ();
    for (line = 1; !feof (data); line++)
    {
	buffer = fgets (data_buffer, sizeof (data_buffer), data);
	if (buffer)
	{
	    Search (line, buffer);
	}
    }
    fclose (data);
    return 0;
}
----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light
 
I like that. you're solving the problem given & not potentially imaginary future senarios of what the problem will become. code to study. thx.
 
You could use icrf's fix or just add struct in front of Pattern in line 23 and line 36. I was using VC++ with the /Tp flag which I have as default. As a result it doesn't pick up on struct being missing. Sorry about that.

Also, I'm not tidying up by freeing memory at the end. It is up to you whether you wish to add that in or not.
 
icrf

Your program compiles no problem but yes I have a feeling I require to use your suggestion -

char temp[6];

sscanf(source,&quot;r%[acdefghiklmnpqrstvxy]r%[acdefghiklmnpqrstvxy]%[acdefghiklmnpqrstvxy]t&quot;,temp);

As otherwise nowhere have we defined what 's' and 't' can be in our patterns.

If so where in the program should it go?

xwb

On inserting the struct the program compiled but see my comments above to icrf.

We are getting there guys and thanks for the support so far.
 
Alright, I don't have time to play with it much right now, but the scanf character classes may not work, they don't have nondeterminism built into them...I didn't really think about it before.

Question for another starting point: will the search pattern always be r?r??s or r?r??t, with ? always being one of that big string of characters, case insensitive? It might be fastest just to build a DFA machine for this specific problem. Oh, and newlines, can they occur in the middle of a pattern, somewhere? Like &quot;r?r?\n?s&quot; ? ----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light
 
as I said I need to learn this stuff so here's a proggie I did for learnin' purposes. I may or may not be what you need.
Code:
/*##########################################################################*/
/* BEWARE ONLY TESTED ON UNIX... DUMB & DIRTY CODE FOLLOWS */
/*##########################################################################*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>

int main(char** argv, int argc){
    FILE*      fileh;
    char       file[20] = &quot;test&quot;;
    int        size;
    char*      pep;
    char*      pos;
    char       pat[256] = &quot;R.R..[RS]&quot;;
    regex_t    rx;
    regmatch_t match[1];
    int        status;
    int        off;

    /*######################################################################*/
    /* Open file * read it into a memory buffer */
    /*######################################################################*/
    if((fileh = fopen(file, &quot;r&quot;)) < 0){
        fprintf(stderr, &quot;Could not open file: %s\n&quot;, file);
        exit(EXIT_FAILURE);
    }
    if(!(size = lseek(fileno(fileh), 0, SEEK_END))){
        fprintf(stderr, &quot;Zero length file: %s\n&quot;, file);
        exit(EXIT_FAILURE);
    }
    if (!(pep = malloc(size))){
        fprintf(stderr, &quot;Ran output of memory\n&quot;);
        exit(EXIT_FAILURE);
    }
    fseek(fileh, 0, SEEK_SET);
    fread(pep, 1, size, fileh);
    fclose(fileh);

    /*######################################################################*/
    /* Build regular expression */
    /*######################################################################*/
    if ((regcomp(&rx, pat, REG_EXTENDED | REG_ICASE))){
        fprintf(stderr, &quot;Could not compile regular expression\n&quot;);
        exit(EXIT_FAILURE);
    }

    /*######################################################################*/
    /* Logic to strip blanks & verify IUPAC string  */
    /* There are ways to eliminate or abbreviate this logic                 */
    /*######################################################################*/

    /*######################################################################*/
    /* Now look for the pattern in memory */
    /*######################################################################*/
    pos = pep;
    off = 0;
    while (!(status = regexec(&rx, pos, 1, match, 0))){
        printf(&quot;beg:%i end:%i\n&quot;, off+match[0].rm_so, off+match[0].rm_eo);
        pos += match[0].rm_so + 1;
        off += match[0].rm_so + 1;
        printf(&quot;%s\n&quot;,pep+off-1);
    }

    /*######################################################################*/
    /* Cleanup & exit */
    /*######################################################################*/
    regfree(&rx);
}
 
icrf

The patterns to be searched are -
r?r??s
OR
r?r??t

This can be upper or lower case and the search is to be made on a set of alphabetic characters which contain from A to Y (excepting B,J,O,U,W)
This can be presented as upper/lower case, on one line or many lines.

So I guess in answer to your question there can be a newline in each of the two patterns being searched for.
This occurs if it is imposible to convert the large string of characters to a single line.
See my initial information at top of this thread

 
Sorry, one day I'll learn to read before I start asking things. Let me try this one: is &quot;acdefghiklmnpqrstvxy&quot; the entire possible character set? Basically what I'm getting to is, if it's not a, r, s, or t, is it in &quot;acdefghiklmnpqrstvxy&quot; (yes, I know those characters are in there, I'm just trying to define specific classes, a,r,s,t,rest if possible). So I won't have to test a character to make sure it's not a 'b' to match it with a '?'

I'm not sure I'm making any sense anymore. I'm going to code up my lovely little parse table and see if it works. I'll post it when done (hopefully not real long). And it has to have the option to search for the *s and *t patterns mutually exclusively? ----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light
 
Well, this hasn't been tested much at all, but I figured I'd throw it up. I made an NFA for the problem, and then converted it to a DFA, whose parse table is listed in the code. The program should find all occurances listed, but it seems the position starting with the second buffer seems to be one short... Hell, here's the code. I'm sorry to do this, but I have something else I have to finish by friday afternoon, so that evening and over the weekend I can look at this again, but I can't until then. Hope it's not too pressing.

In theory, this method of doing the search should be the fastest. The regex libraries make it a heck of a lot easier, but this is a very specific solution for a very specific problem. I suppose I could even try and reduce the number of states in the machine, too, haven't checked to see if that's possible yet. I'll check back here in a couple days. There's a good chance there's some fundamental problems that cause it skip things...but I'm pretty sure it's in the implimentation, not in the machine.

Code:
#include <stdio.h>
#include <string.h>

/* search terminating in s or t */
#define pttrn 't'

/* size of buffer, doesn't mean much here, but I'm
   assuming you're not going to hard-code your search
   string in and read it from a file or something */
#define buffer_length 50

/* length of the pattern */
#define pattern_length 6

/* which state is the final state */
#define final 15

int main(void)
{
	int row0[] = {1,3,4,5,7,8,10,12,14,1,5,4,8,10,14};
	int row1[] = 
{0,2,0,2,6,6,9,11,13,final,final,final,final,final,final};
	int row2[] = {0,2,0,2,6,6,9,11,13,0,6,0,6,9,13};
	
	int *rules[3],tot_index,i,state,src_len;
	char *source 
= &quot;mwaaagglwrsraglralfrsrdaalfpgcerglhcsavscknwlkkfasktkkkvw
yespslgshstykpskleflmrstskktrkedharlralngllykaltdllctpevsqel
ydlnvelskvsltpdfsacraywkttlsaeqnahmeavlqrsaahmslisywqsqtldpg
mkettlykmisgtlmphnpaapqsrpqapvcvgsimrrstsrlwstkggkikgsgawcgr
grwls&quot;;
	char buffer[buffer_length];
	char temp[pattern_length+1];

	rules[0] = row0;
	rules[1] = row1;
	rules[2] = row2;
	src_len = strlen(source);
	tot_index = 0;

	while(tot_index < src_len)
	{
		strncpy(buffer,source+sizeof(char)
*tot_index,buffer_length);
		state = 0;
		
		for(i=0;(i<(buffer_length-pattern_length)) 
&& (tot_index < src_len);i++)
		{
			switch(buffer[i])
			{
			case 'r':		state = 
rules[0][state]; break;
			case pttrn :	state = rules[1]
[state]; break;
			default :		state = 
rules[2][state]; break;
			}

			if(state == final)
			{
				/* offest from the total 
index minux the length of the pattern, plus one for zero 
index */
				strncpy(temp,source+(sizeof
(char)*(tot_index-pattern_length+1)),pattern_length);
				temp[pattern_length] 
= '\0'; /* terminate string with null so it can be printed 
*/
				printf(&quot;The string \&quot;%s\&quot; 
occured %d characters from the start.\n&quot;,temp,(tot_index-
pattern_length+1));
				state = 0;
			}
			tot_index++;
		}
		if(tot_index < src_len)
		{
			tot_index -= pattern_length; /* in 
case the pattern stretches between buffers */
		}
	}
	return 0;
}
--------------------------------------------------------
...but I'm just a C man trying to see the light
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top