File searching, replacing, copying...

A. First Edition
This is comp444 lab1 and it is concentrated on file operations such as searching, replacing, copying...
I want to keep this simple version for possible future modification.
B.The problem

Open a file and search a word with starting of your argument.

C.The idea of program
 

From point of view of compiler project, it is a toy scanner with much simplified functionality. But it is

difficult for me to debug c in Linux. Another reason is the awkward C grammar. There is no "bool" type, there

is no function overloading, there is no ...

D.The major functions
 
E.Further improvement
 
F.File listing
1. myhead.h
2. searchString.h
3. searchString.c
4. main.c
5. errHandle.c
6. makefile
 
 
file name: myhead.h
#ifndef MYHEAD_H
#define MYHEAD_H

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

typedef int bool;

#define TRUE  1
#define FALSE 0

#define BuffSize   128

void errHandle(char* msg);

	
#endif
 
file name: searchString.h
#ifndef SEARCHSTRING_H
#define SEARCHSTRING_H

#include "myhead.h"

struct FileBuf
{
	int fd;
	int size;
	int offset;
	int cur;
	char buf[128];
	//char buf[BuffSize];
}fileBuf;

typedef struct FileBuf* FilePtr;

int findString(char* fileName, char* str);

//define three mode and it is purely like DFA=Deterministic Finite Automaton
#define FindNextWord   	0
#define SkipTillNext	1
#define Comparing	2

//search in a file with my own file information struct FileBuf*, 
//target is the string for searching
//repeating call this function and return each location, 
//return -1 indicating end of file
int searchString(FilePtr stream, char* target);

//specify if it is white space char
//notice here, in C, there is no boolean type and I define it
//as alias of int in "myhead.h"
bool isBreak(char ch);

//my edition of getc
FilePtr openFile(int fd);

//a-z, A-Z
bool isChar(char ch);

//my edition of getc
char nextChar(struct FileBuf* stream);

#endif
 
file name: searchString.c
#include "myhead.h"
#include "searchString.h"


bool findString(char* fileName, char* str)
{
	int fd, n=0;
	FilePtr stream;
	bool result=FALSE;
	if ((fd=open(fileName, O_RDONLY))<0)
	{
		errHandle("cannot open searching files\n");
	}
	if ((stream=openFile(fd))==NULL)
	{
		errHandle("openfile error\n");
	}
	while ((n=searchString(stream, str))!=-1)
	{
		result=TRUE;
		printf("test: find target at %d\n", n);
	}
	return result;
}


//my edition of "fopen"
FilePtr openFile(int fd)
{
	fileBuf.fd=fd;
	fileBuf.offset=0;
	if ((fileBuf.size=read(fd, fileBuf.buf, BuffSize))<0)
	{
		return NULL;
	}
	fileBuf.cur=0;
	return &fileBuf;
}

//getc
char nextChar(FilePtr stream)
{
	//if buff is fully read
	if (stream->cur >= stream->size)
	{
		if (stream->size==0)//must be end of file
		{
			return -1;
			//return EOF;
		}
		//if erro happened during reading
		if ((stream->size=read(stream->fd, stream->buf, BuffSize))<0)
		{
			errHandle("read error of file buf\n");
		}
		//reset cur
		stream->cur=0;
	}
	//offset is always inc for each call
	stream->offset++;
	return stream->buf[stream->cur++];
}
	
//what is white space
bool isBreak(char ch)
{
	return (ch==' '||ch=='\t'||ch=='\n');
}

bool isChar(char ch)
{
	return ((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'));
}

//starting a particular file offset and search the target string
//if found return the file offset of target, else return -1
int searchString(FilePtr stream, char* target)
{
	int stringLength=strlen(target);
	char ch;
	int result=-1;//this is the starting offset of word
	//the length of word compared
	int length;
	int mode;
	length=0;
	mode=FindNextWord;//initial status
	//-1 means EOF
	while ((ch=nextChar(stream))!=-1)
	{
		switch (mode)
		{
		case FindNextWord:
			if (isChar(ch))
			{
				//check the very first 
				if (ch==target[0])
				{
					mode=Comparing;
					length=1;//need to compare with next
					result=stream->offset-1;//as it already passed it
				}
				else
				{
					mode=SkipTillNext;
				}				
			}
			//else keep going
			break;
		case SkipTillNext:
			if (isBreak(ch))
			{
				mode=FindNextWord;
			}
			break;				
		case Comparing:
			//it is a match
			if (ch==target[length])
			{
				//a match then keep going
				length++;
			        //a white space
                        	if (length==stringLength)
                        	{
                                	return result;
                        	}
			}
			else
			{
				//it means mis-match
				mode=SkipTillNext;
			}
			break;
		}//switch
	}//while					
	return -1;
}		
						

		
file name: errHandle.c
#include "myhead.h"


void errHandle(char* msg)
{
	if (msg!=NULL)
	{
		perror(msg);
	}
	else
	{
		strerror(errno);
	}		
	exit(errno);
}
	
file name: makefile
all: searchString.o  main.o errHandle.o
	@echo "make complete for searchString.o "

errHandle.o : errHandle.c myhead.h
	@echo "compiling errHanle module\n"
	gcc -g -c errHandle.c -o errHandle.o

main.o : searchString.o main.c errHandle.o
	gcc -g main.c searchString.o errHandle.o -o main.o
	@echo "compiling main.o ..." 

searchString.o : searchString.h searchString.c myhead.h
	gcc -g -c searchString.c -o searchString.o
	@echo "compiling searchString.o as searchString.c is modified..."

 




How to run?
1. You need the file name as argument in command line
[qingz_hu@alamanni ~/lab1] % ./main.o test.txt
test: find target at 0
test: find target at 39
test: find target at 92
test: find target at 127
test: find target at 334
ok




                                 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)