Archived

This topic is now archived and is closed to further replies.

searching through the contents of a file

This topic is 5047 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i recently came across a nice little bit of c code that searches through a file for any string of text (or data for that matter it doesnt necessarily have to be "text"). for a while this suited my needs quie nicely until i did some extensive testing of this little pair of functions and found there was a HUGE limitation. it seems that it allocates a static buffer (im assuming for the searching process, the code isnt exactly pretty, but it DOES work) and when the buffer is all used up it fails in any further attempts to search. i ran across this problem when searching through a large directory with many files. my question is there a way to get around this with the given code? or better yet is there a tried and true way of searching within files for a pattern of text, something along the lines of FindFirstFile (as in something that works, works well (from my experience) and i can count on)? here is the code, i did not write this, and it IS very ugly... especialy the goto statements. but... it works...
static size_t fsetup(FILE *fp, size_t minbuf)
{
	register size_t bufsize;
	register char* buffer;
	
	/* Allocate the largest buffer we can */
	
	for (bufsize = 0x4000; bufsize >= minbuf; bufsize >>= 1)
	{
		if (NULL != (buffer = (char* ) malloc(bufsize)))
			break;
	}
	if (NULL == buffer)
		return 0;
	
	/* Use the buffer to buffer the file */
	
	if (0 == setvbuf(fp, buffer, _IOFBF, bufsize))
		return bufsize;
	else  return 0;
}

long ffsearch(FILE *fp, const char* pattern, const size_t size, int N)
{
	long pos = -2L, tempos = 0L;
	char* sbuf, *p;
	size_t skip;
	int ch = 0;
	
	/* Allocate a search buffer */
	
	if (NULL == (sbuf = (char* )malloc(size - 1)))
		goto FDONE;
	
	/* Buffer the file and position us within it */
	
	if (0 == fsetup(fp, size))
		goto FDONE;
	pos = -1L;
	fseek(fp, 0L, SEEK_SET);
	
	/* Set up for smart searching */
	
	if (1 < strlen(pattern) && NULL != (p = strchr(pattern + 1, *pattern)))
		skip = p - (char* )pattern;
	else  skip = strlen(pattern);
	
	/* Look for the pattern */
	
	while (EOF != ch)
	{
		if (EOF == (ch = fgetc(fp)))
			break;
		if ((int)*pattern == ch)
		{
			tempos = ftell(fp);
			if (size - 1 > fread(sbuf, sizeof(char), size - 1, fp))
				goto FDONE;
			if (0 == memcmp(sbuf, &pattern[1], size - 1))
			{
				if (0 == --N)
				{
					pos = tempos - 1L;
					goto FDONE;
				}
			}
			fseek(fp, tempos + skip, SEEK_SET);
		}
	}
	
	/* Clean up and leave */
	
FDONE:
	free(sbuf);
	return pos;
}
Bungo!

Share this post


Link to post
Share on other sites