Linux file operations

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