zoukankan      html  css  js  c++  java
  • 一个简单的文本编译器

    花了几天,从没有思路到写完。因为是第一次写这种命令交互式的,所以bug会很多。

    格式:E/e:指定要编辑的文件

       Q/q:结束编辑

       R/r(用r命令后继的k行正文代替原始正文中的m行到n行)

        R  k m n

         k行正文

       I/i(将i命令后继的k行正文插入到原始正文第m行之后)

        I k m

         k行正文

       D/d(将原始正文中的第m行到第n行的正文内容删除)

        D m n

    这是我写的代码:

      1 /* 实现简单的文本编辑器 */
      2 /* bug1:先按e,再按文件名,循环后ch还是等于'
    ' */
      3 /* bug2:插入函数中,要是正文的一行最后不是回车的话,则插入的第一行会在所插的那一行上面,没有分开 */
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 #define    CHMAX    80    /* 一行最多80个字符 */
      9 #define    LINEMAX    200    /* 最多允许200行 */
     10 
     11 char command[] = "EeRrIiDdQq";    /* 可选择的命令 */
     12 char buffer[CHMAX];            /* 输入的缓冲区 */
     13 char *Line[LINEMAX];    /* 行指针,用来输入一行 */
     14 char *chpt;    /* 获取命令及参数的字符指针 */
     15 char filename[256];    /* 输入的文件名 */
     16 int modified = 0;    /* 修改标志 */
     17 int last;    /* 文本的最后一行,没有内容 */
     18 void Edit(), Replace(), Insert(), Delete(), Quit();
     19 void (*comfunc[])() = {Edit, Replace, Insert, Delete, Quit};    /* 函数指针数组 */
     20 void call();
     21 
     22 int main(void)
     23 {
     24     call();
     25     return 0;
     26 }
     27 
     28 void call()
     29 {
     30     int    j = 0;
     31     char    ch;
     32     last = 0;
     33 
     34     while (1)
     35     {
     36         j = 0;
     37         printf("Input a command: [e,r,i,d,q]
    ");
     38 
     39         /* bug1 */
     40         //ch = ' ';
     41         //fflush(stdin);
     42         while ((ch = fgetc(stdin)) != '
    ')        /* 输入命令 */
     43         {
     44             buffer[j] = ch;
     45             j++;
     46         }
     47         buffer[j] = '';
     48         
     49         for (chpt = buffer; *chpt == ' ' || *chpt == '	'; chpt++)    /* 跳过空白符 */
     50             ;
     51         
     52         if (*chpt == '')
     53         {
     54             printf("Doesn't input any command
    ");
     55             continue;
     56         }
     57     
     58         for (j = 0; command[j] != *chpt && command[j] != ''; j++)    /* 获取命令的序号 */
     59             if (command[j] == '')
     60             {
     61                 printf("Cannot find command.
    ");
     62                 continue;
     63             }
     64         chpt++;            /* 指向参数 */
     65         (*comfunc[j/2])();    /* 执行相应的函数 */
     66 
     67         printf("The text is:
    ");
     68         for (j = 0; j < last; j++)    /* 输出text的内容 */
     69             fputs(Line[j], stdout);
     70     }
     71 
     72 }
     73 
     74 void Edit()
     75 {
     76     int    i;
     77     FILE    *fp_temp;    /* 临时的文件指针 */
     78 
     79     i = sscanf(chpt, "%s", filename);    /* sscnaf函数返回值是参数的个数,参数应当只有一个 */
     80 
     81     if (i != 1)    /* 没有输入文件名或者输入超过一个文件名 */
     82     {
     83         printf("not input filename or more than 1 file, please input filename again:
    ");
     84         scanf(" %s", filename);
     85     }
     86 
     87     /* 打开指定文件,没有就创建新的文件 */
     88     if ((fp_temp = fopen(filename, "r")) == NULL)    /* 没有这个文件,则创建新的文件 */
     89     {
     90         if ((fp_temp = fopen(filename, "w")) == NULL)/*  创建新的文件 */
     91         {
     92             printf("Cannot create a new file");
     93             return;
     94         }
     95         fclose(fp_temp);
     96         if ((fp_temp = fopen(filename, "r")) == NULL)
     97         {
     98             printf("Cannot read");
     99             return;
    100         }
    101     }
    102                                                                                                                    
    103     i = 0;
    104     while ((fgets(buffer, CHMAX, fp_temp)) == buffer)    /* 不用担心buffer越界问题,因为接下来没有使用到buffer */
    105     {
    106         Line[i] = (char *)malloc((strlen(buffer)) + 1);
    107         strcpy(Line[i], buffer);
    108         i++;
    109     }
    110     last = i;    
    111     
    112     fclose(fp_temp);
    113     modified = 1;    /* 已修改 */
    114 }
    115 
    116 void Replace()
    117 {
    118     int    i, k, m, n;    /* 将k行正文替换到第m行和第n行中 */
    119     
    120     if (modified != 1)
    121     {
    122         printf("Did not open a file.
    ");
    123         return;
    124     }
    125 
    126     i = sscanf(chpt, "%d%d%d", &k, &m, &n);
    127     if (i != 3 || m < 0 || n < 0 || k < 0 || m > n || n > last || k > last)
    128     {
    129         printf("format error
    ");
    130         return;
    131     }
    132 
    133     
    134     if (k != (n-m+1))
    135     {
    136         printf("error number of lines replaced.
    ");
    137         return;
    138     }
    139 
    140     /* 写k行正文 */
    141     printf("Please input %d line words:
    ", k);
    142 
    143     /* 替换 */
    144     for (i = 0; i < k; i++)
    145     {
    146         free(Line[m+i-1]);
    147         fgets(buffer, CHMAX, stdin);
    148         Line[m+i-1] = (char *)malloc(strlen(buffer) + 1);
    149         strcpy(Line[m+i-1], buffer);
    150     }
    151         
    152     modified = 1;
    153 }
    154 
    155 void Insert()
    156 {
    157     int    i, k, m;    /* 将k行正文插入到原始正文第m行之后 */
    158     
    159 
    160     if (modified != 1)    /* Edit最后修改modified标志 */
    161     {
    162         printf("Did not open a file.
    ");
    163         return;
    164     }
    165     
    166     i = sscanf(chpt, "%d%d", &k, &m);
    167     
    168     if (i != 2 || k < 0 || m < 0 || last + k >= LINEMAX)
    169     {
    170         printf("format error.
    ");
    171         return;
    172     }
    173 
    174     /* 写k行正文 */
    175     printf("Please input %d line words:
    ", k);
    176 
    177     /* 先将原文的第m+1行开始都向后移k行 */
    178     for (i = last-1; i > m-1; i--)
    179     {    
    180         Line[i+k] = Line[i];/* 向后移k行 */
    181     }
    182     
    183     /* 再将中间的k行补上 */
    184     for (i = 0; i < k; i++)
    185     {
    186         fgets(buffer, CHMAX, stdin);
    187         Line[m+i] = (char *)malloc(strlen(buffer) + 1);
    188         strcpy(Line[m+i], buffer);
    189     }
    190     
    191     last += k;    /* 给原来的last增加k行 */
    192     modified = 1;    /* 已修改 */
    193 }
    194 
    195 void Delete()
    196 {
    197     int    i, j, m, n;    /* 删去原始正文的第m行到第n行内容 */
    198 
    199     if (modified != 1)
    200     {
    201         printf("Did not open a filen
    ");
    202         return;
    203     }
    204     
    205     i = sscanf(chpt, "%d%d", &m, &n);
    206     if (i != 2 || m < 0 || n < 0 || m >n || n > last)
    207     {
    208         printf("format error
    ");
    209         return;
    210     }
    211 
    212     /* 先删去,再移位 */
    213     for (i = 0; i < (n-m+1); i++)
    214         free(Line[m+i-1]);
    215     for(i = n, j = 0; i < last; i++, j++)
    216         Line[m+j-1] = Line[i];
    217     last -= (n-m+1);
    218 
    219     modified = 1;
    220 }
    221 
    222 void Quit()
    223 {
    224     int    i;
    225     char    flag;
    226     FILE    *fp_temp;
    227 
    228     printf("Save? y/n:");    
    229     scanf(" %c", &flag);
    230 
    231     if (flag == 'Y' || flag == 'y')
    232     {
    233         if ((fp_temp = fopen(filename, "w")) == NULL)
    234         {
    235             printf("Cannot open a file");
    236             exit(1);
    237         }
    238         for (i = 0; i < last; i++)
    239             fputs(Line[i], fp_temp);
    240         printf("save successfully!
    ");
    241     }
    242     else
    243     ;
    244     exit(0);
    245 
    246 }
    View Code

    下面给出运行结果:

     

     

    ps:最好都是每一行都会有回车键,因为fgets函数是指定字符数的。具体看代码就应该知道了。

    有兴趣的同学可以改进!

  • 相关阅读:
    程序员学习视频教程汇总
    分享一个单机软件试用期计时思路
    C# XML转Json Json转XML XML 转对象 对象转XML
    C# 数独 解法
    C# 炸弹人 winform版
    胃食管反流疾病认识总结
    C# Datagridview combox列 初始化颜色
    C# WPF 坦克大战
    高分辨率食道测压(HRM)
    C# wpf 使用 polyline 做一个贪吃蛇游戏的小蛇移动吃食部分功能
  • 原文地址:https://www.cnblogs.com/fusae-blog/p/4269652.html
Copyright © 2011-2022 走看看