A command line-based text editor

Source: Internet
Author: User

Implement a command line-based text editor

Function:
1. Open a file
2. Save the file
3. Searching for files
4. Ability to replace files
5. Ability to delete files

/*
File: textproc. h
Compiler: Dev-C ++ OR TC2.0 (# define COMPILER_TC)
Define Macros And Tool Functions
*/

/* Define Result File Name */
# Define RESULT_FILE_NAME "010588_result.txt"

/* Define Debug Flag */
/* # Define DO_DEBUG 1 */

/* Define Compiler Flag Dev-C ++ OR TC2.0 */
/* # Define COMPILER_TC 1 */

/* Define Error Code */
# Define ERR_OPTR_UNKOWN-1
# Define ERR_OPND_NOT_MATCH-2
/* # Define ERR_DIR_FMT_INVALID-3 */
# Define ERR_FILE_CANT_FOUND-4
# Define err_file_cant_open-5
# Define err_file_write_error-6
# Define err_file_read_error-7
# Define err_memory_overflow-8

/* Define max value */
# Define max_arg_num 5
# Define max_cmd_len 1024
# Define max_str_len 256

/* Define for envtype */
Typedef struct
{
Char exepath [max_str_len + 1];
Char curpath [max_str_len + 1];
Int textlen;
Char * text;
Int arrlen;
Char * arr;
} Envtype;

/* Define for ffblk struct for tc2.0 */
Typedef struct
{
Char ff_reserved [21];/* DOS Reserved Word */
Char ff_attrib;/* File Attrib */
Int ff_ftime;/* File Time */
Int ff_fdate;/* File Date */
Long ff_fsize;/* File Size */
Char ff_name [13];/* File Name */
} Ffblk;

/* Split fileName, Extract pathName */
Int SplitDir (char pathName [], char fileName [])
{
Int I, flag = 1;
If (fileName [0]! = '//' & FileName [1]! = ':')
Flag = 0;
For (I = strlen (fileName)-1; I> = 0 & fileName [I]! = '//'; I --);
PathName [I + 1] = '/0 ';
While (I> = 0)
{
PathName [I] = fileName [I];
I --;
}
Return flag;
}

/* Dynamic Programming, Calc nextVal for KMP */
Void GetNextVal (int nextVal [], char T [], int T_len)
{
Int I = 0, j =-1;
NextVal [0] =-1;
While (I <T_len-1)
{
If (j =-1 | T [I] = T [j])
{
++ I; ++ j;
If (T [I]! = T [j])
NextVal [I] = j;
Else
NextVal [I] = nextVal [j];
}
Else
J = nextVal [j];
}
}

/* Index SubString (KMP )*/
Int IndexKMP (char S [], int S_len, char T [], int T_len, int nextVal [], int pos)
{
Int I = pos, j = 0;
While (I <S_len & j <T_len)
{
If (j =-1 | S [I] = T [j])
{
++ I; ++ j;
}
Else
J = nextVal [j];
}
If (j> = T_len)
Return i-T_len;
Else
Return-1;
}

/* Basic operation: Mark markarr array, using KMP Index */
Int getmarkarr (INT markarr [], char s [], int s_len, char T [], int t_len)
{
Int I, res, nextval [max_str_len], markcnt = 0;
Getnextval (nextval, T, t_len );
# Ifdef do_debug
Printf ("nextval_debug_begin/nnextval:/N ");
For (I = 0; I <t_len; I ++)
Printf ("% d", nextval [I]);
Printf ("/nnextval_debug_end/N ");
# Endif
For (I = 0; I <s_len; I ++)
Markarr [I] = 0;
I = 0;
Do {
Res = indexkmp (S, s_len, T, t_len, nextval, I );
If (res! =-1)
{
MarkArr [res] = 1;
MarkCnt ++;
I = res + T_len;
}
} While (I <S_len & res! =-1 );
Return markCnt;
}

/* Basic operation: Replace SubString */
Void ReplaceStr (char arr [], char text [], int textLen, int markArr [], int lenSrc, char strDest [], int lenDest)
{
Int I = 0, j = 0, k;
While (I <textLen)
{
If (markArr [I])
{
For (k = 0; k <lenDest; k ++)
{
Arr [j] = strDest [k];
J ++;
}
I + = lenSrc;
}
Else
{
Arr [j] = text [I];
J ++; I ++;
}
}
}

/*
File: textproc. cpp
Compiler: Dev-C ++ OR TC2.0 (# define COMPILER_TC)
Text Process Tools
*/

# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <io. h>
# Include "textproc. h"

/* Open File Proc for Cmd "-o "*/
Int OpenProc (EnvType * env, char fileName [])
{
Char pathname [max_str_len + 1], TMP [max_str_len + 1];
# Ifdef compiler_tc
Ffblk fileinfo;
# Else
Struct _ finddata_t fileinfo;
# Endif
Int filehandle;
File * FP;
If (! Splitdir (pathname, filename ))
{
Strcpy (TMP, env-> exepath );
Strcat (TMP, pathname );
Strcpy (pathname, TMP );
Strcpy (TMP, env-> exepath );
Strcat (TMP, filename );
Strcpy (filename, TMP );
/* Return err_dir_fmt_invalid ;*/
}
# Ifdef compiler_tc
Filehandle = findfirst (filename, & fileinfo );
# Else
FileHandle = _ findfirst (fileName, & fileInfo );
# Endif
If (fileHandle =-1)
Return ERR_FILE_CANT_FOUND;
# Ifndef COMPILER_TC
_ Findclose (fileHandle );
# Endif
Fp = fopen (fileName, "rb ");
If (fp = NULL)
Return ERR_FILE_CANT_OPEN;
If (env-> text! = NULL)
{
Free (env-> text );
Env-> text = NULL;
Env-> textLen = 0;
}
If (env-> arr! = NULL)
{
Free (env-> arr );
Env-> arr = NULL;
Env-> arrLen = 0;
}
Strcpy (env-> curPath, pathName );
# Ifdef COMPILER_TC
Env-> textLen = fileInfo. ff_fsize;
# Else
Env-> textLen = fileInfo. size;
# Endif
Env-> text = (char *) malloc (env-> textLen * sizeof (char ));
If (env-> text = NULL)
Return ERR_MEMORY_OVERFLOW;
If (fread (env-> text, sizeof (char), env-> textLen, fp )! = Env-> textLen)
{
Fclose (fp );
Return ERR_FILE_READ_ERROR;
}
Fclose (fp );
Return 0;
}

/* Save File Proc for Cmd "-s "*/
Int SaveProc (EnvType * env, char fileName [])
{
Char pathname [max_str_len + 1], TMP [max_str_len + 1];
File * FP;
If (! Splitdir (pathname, filename ))
{
Strcpy (TMP, env-> exepath );
Strcat (TMP, pathname );
Strcpy (pathname, TMP );
Strcpy (TMP, env-> exepath );
Strcat (TMP, filename );
Strcpy (filename, TMP );
/* Return err_dir_fmt_invalid ;*/
}
Fp = fopen (filename, "WB ");
If (FP = NULL)
Return err_file_cant_open;
If (env-> Arr! = NULL)
{
Free (env-> text );
Env-> text = env-> arr;
Env-> textLen = env-> arrLen;
Env-> arr = NULL;
Env-> arrLen = 0;
}
Strcpy (env-> curPath, pathName );
If (fwrite (env-> text, sizeof (char), env-> textLen, fp )! = Env-> textLen)
{
Fclose (fp );
Return ERR_FILE_WRITE_ERROR;
}
Fclose (fp );
Return 0;
}

/* Find SubString, for Cmd "-f "*/
Int FindProc (EnvType * env, char strFind [], int strLen)
{
Int I, markCnt, * markArr = (int *) malloc (env-> textLen * sizeof (int ));
Char fileName [MAX_STR_LEN + 1];
FILE * fp;
If (markArr = NULL)
Return ERR_MEMORY_OVERFLOW;
MarkCnt = GetMarkArr (markArr, env-> text, env-> textLen, strFind, strLen );
Printf ("-f % d/n", markCnt );
# Ifdef DO_DEBUG
Printf ("MARKARR_DEBUG_BEGIN/nmarkArr:/n ");
For (I = 0; I <env-> textLen; I ++)
Printf ("% d", markArr [I]);
Printf ("/nMARKARR_DEBUG_END/n ");
# Endif
Strcpy (fileName, env-> curPath );
Strcat (fileName, RESULT_FILE_NAME );
Fp = fopen (fileName, "AB ");
If (fp = NULL)
Return ERR_FILE_CANT_OPEN;
Fprintf (fp, "-f % d/r/n", markCnt );
Free (markArr );
Fclose (fp );
Return 0;
}

/* Replace string and delete substring for cmd "-R" and "-d "*/
Int replaceproc (envtype * ENV, char strsrc [], int lensrc, char strdest [], int lendest)
{
Int I, markcnt, * markarr = (int *) malloc (env-> textlen * sizeof (INT ));
Char filename [max_str_len + 1];
File * FP;
If (markarr = NULL)
Return err_memory_overflow;
Markcnt = getmarkarr (markarr, env-> text, env-> textlen, strsrc, lensrc );
If (lendest = 0)
Printf ("-D % d/n", markcnt );
Else
Printf ("-R % d/n", markcnt );
# Ifdef do_debug
Printf ("markarr_debug_begin/nmarkarr:/N ");
For (I = 0; I <env-> textlen; I ++)
Printf ("% d", markarr [I]);
Printf ("/nmarkarr_debug_end/N ");
# Endif
Strcpy (filename, env-> curpath );
Strcat (filename, result_file_name );
Fp = fopen (filename, "AB ");
If (FP = NULL)
Return err_file_cant_open;
If (lendest = 0)
Fprintf (FP, "-D % d/R/N", markcnt );
Else
Fprintf (FP, "-R % d/R/N", markcnt );
If (env-> Arr! = NULL)
{
Free (env-> ARR );
Env-> arr = NULL;
Env-> arrlen = 0;
}
Env-> arrlen = env-> textlen + markcnt * (lendest-lensrc );
Env-> arr = (char *) malloc (env-> arrlen * sizeof (char ));
If (env-> arr = NULL)
Return ERR_MEMORY_OVERFLOW;
ReplaceStr (env-> arr, env-> text, env-> textLen, markArr, lenSrc, strDest, lenDest );
Free (markArr );
If (fwrite (env-> arr, sizeof (char), env-> arrLen, fp )! = Env-> arrLen)
{
Fclose (fp );
Return ERR_FILE_WRITE_ERROR;
}
Fprintf (fp, "/r/n ");
Fclose (fp );
Return 0;
}

/* Init WorkSpace */
Void Init (EnvType * env)
{
Getcwd (env-> exePath, MAX_STR_LEN );
Strcat (env-> exePath ,"//");
Env-> curPath [0] = '/0 ';
Env-> text = env-> arr = NULL;
Env-> textLen = env-> arrLen = 0;
}

/* Clear WorkSpace */
Void Clear (EnvType * env)
{
If (env-> text! = NULL)
{
Free (env-> text );
Env-> text = NULL;
Env-> textLen = 0;
}
If (env-> arr! = NULL)
{
Free (env-> arr );
Env-> arr = NULL;
Env-> arrLen = 0;
}
}

/* Read Cmd Line */
Int ReadCmd (int * argc, char argv [] [MAX_STR_LEN + 1], int argl [])
{
Int I;
Char line [MAX_CMD_LEN + 1];
Gets (line );
* Argc = 0;
Argl [* argc] = 0;
For (I = 0; line [I]! = '/0'; I ++)
{
If (line [I] = ''| line [I] = '/t ')
{
If (argl [* argc]> 0)
{
Argv [* argc] [argl [* argc] = '/0 ';
(* Argc) ++;
Argl [* argc] = 0;
}
}
Else
{
Argv [* argc] [argl [* argc] = line [I];
Argl [* argc] ++;
}
}
If (argl [* argc]> 0)
{
Argv [* argc] [argl [* argc] = '/0 ';
(* Argc) ++;
}
If (* argc = 1 & strcmp (argv [0], "-q") = 0)
Return 0;
Else
Return 1;
}

/* Display Usage */
Void DisplayUsage ()
{
Printf ("pai_format: OPTR [OPND1 [OPND2]/n ");
Printf ("OPTR pai_type OPND_LIST/n ");
Printf ("-o Open File. OPND1 = filename/n ");
Printf ("-h Help Info./n ");
Printf ("-s Save File. OPND1 = filename/n ");
Printf ("-F find substring. opnd1 = stringtofind/N ");
Printf ("-R replace substring. opnd1 = sourcestring/N ");
Printf ("opnd2 = targetstring/N ");
Printf ("-D Delete substring. opnd1 = stringtodelete/N ");
Printf ("-Q quit./N ");
Printf ("-e display env Info (Debug)./N ");
}

/* Display env info for debug */
Void displayenv (envtype env)
{
Int I;
Printf ("env_debug_begin/nexepath = % s/n", env.exe path );
Printf ("curpath = % s/n", ENV. curpath );
Printf ("textlen = % d, text:/N", ENV. textlen );
Printf ("-------------------/n ");
For (I = 0; I <env. textLen; I ++)
Printf ("% c", env. text [I]);
Printf ("/n -------------------/n ");
Printf ("arrLen = % d, arr:/n", env. arrLen );
Printf ("-------------------/n ");
For (I = 0; I <env. arrLen; I ++)
Printf ("% c", env. arr [I]);
Printf ("/n -----------------/nENV_DEBUG_END/n ");

}

/* Display Error Info for Debug */
Void DisplayError (int errCode)
{
Switch (errCode)
{
Case ERR_FILE_READ_ERROR: printf ("ERR_FILE_READ_ERROR/n"); break;
Case ERR_FILE_WRITE_ERROR: printf ("ERR_FILE_WRITE_ERROR"); break;
/* Case err_dir_fmt_invalid: printf ("err_dir_fmt_invalid/N"); break ;*/
Case err_file_cant_found: printf ("err_file_cant_found/N"); break;
Case err_file_cant_open: printf ("err_file_cant_open/N"); break;
Case err_memory_overflow: printf ("err_memory_overflow/N"); break;
Case err_optr_unkown: printf ("err_optr_unkown/N"); break;
Case err_opnd_not_match: printf ("err_opnd_not_match/N"); break;
Default: printf ("err_unkown/N ");
}
}

/* Main function */
Int main ()
{
Envtype env;
Int I, argc, argl [max_arg_num + 1], errcode;
Char argv [max_arg_num + 1] [max_str_len + 1];

Init (& env );
While (readcmd (& argc, argv, argl ))
{
# Ifdef do_debug
Printf ("arg_debug_begin/nargc = % d/N", argc );
For (I = 0; I <argc; I ++)
Printf ("% d % s/n", argl [I], argv [I]);
Printf ("arg_debug_end/N ");
# Endif
If (argc = 0 | argl [0]! = 2 | argv [0] [0]! = '-')
{
Displayusage ();
Continue;
}
Errcode = 0;
Switch (argv [0] [1])
{
Case 'O': If (argc! = 2)
Errcode = err_opnd_not_match;
Else
Errcode = openproc (& ENV, argv [1]);
Break;
Case 'H': If (argc! = 1)
Errcode = err_opnd_not_match;
Else
Displayusage ();
Break;
Case's ': If (argc! = 2)
Errcode = err_opnd_not_match;
Else
Errcode = saveproc (& ENV, argv [1]);
Break;
Case 'F': If (argc! = 2)
Errcode = err_opnd_not_match;
Else
Errcode = findproc (& ENV, argv [1], argl [1]);
Break;
Case 'r': If (argc! = 3)
Errcode = err_opnd_not_match;
Else
Errcode = replaceproc (& ENV, argv [1], argl [1], argv [2], argl [2]);
Break;
Case 'D': if (argc! = 2)
ErrCode = ERR_OPND_NOT_MATCH;
Else
ErrCode = ReplaceProc (& env, argv [1], argl [1], "", 0 );
Break;
Case 'q': if (argc! = 1)
ErrCode = ERR_OPND_NOT_MATCH;
Break;
Case 'E': if (argc! = 1)/* Used For Debug */
ErrCode = ERR_OPND_NOT_MATCH;
Else
DisplayEnv (env );
Break;
Default: errCode = ERR_OPTR_UNKOWN;
}
# Ifdef DO_DEBUG
DisplayEnv (env );
# Endif
If (errCode! = 0)
DisplayError (errCode );

}
Clear (& env );
 
Return 0;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.