c语言版去除源代码注释

来源:互联网 发布:淘宝领域数码怎么样 编辑:程序博客网 时间:2024/06/05 02:19
  1. 去除代码中注释需要注意下面几点
    首先注释有”/*”开始到”*/”结束的多行或单行注释
    其次还有”//”这种单行注释
    另外还需要注意双引号和单引号内的字符不要算到注释中
  2. 因此我设计以下程序
    当遇到”“双引号和”“时需要跳过整个字符串,特别注意字符串和字符内部转义字符。
    当遇到”/“斜杠时,匹配下一个为星号还是斜杠,如果下一个是斜杠则直接跳到本行结尾。如果是星号则匹配”*/
  3. 下面是源代码,没啥特别的
#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <fcntl.h>#include <sys/stat.h>/*** 去掉字符串中注释部分**/void remove_comment(char *buf){  size_t off;  char *s, *p, *t, *tmp;  char *sss="adas\"d/**/\"*a\"//s/**/d*/"; // 这里主要测试字符串内带注释字符  for (s = p = buf; *p != '\0'; p++) {    switch(*p) {      case '"': // 直接循环到下一个 "      case '\'': /* 直接循环到下一个 ' */          // 下面找到字符串结束位置,避免匹配字符串内部的 /* 或者 //        for (tmp = p + 1; *tmp != *p; tmp++) {          if (*tmp == '\\') {            tmp++; /* 跳过转义位置,因为转义字符2个位置代表一个字符 */          }        }//阿萨德撒        // while(1) {          // if ( NULL != (t = strchr(tmp, '\\')) ) {        // printf("%c\n", *tmp);            // tmp = t + 2; // 有转义字符          // }          // if ( NULL != (t = strchr(tmp, *p)) ) {            // tmp = t + 1; // 有要找的字符            // break;          // }        // }        // printf("%c\n", *(tmp-2));        // exit(0);        // while ( NULL != (t = strchr(tmp, *p)) ) {          // tmp = t + 1; /*每次都从下一个位置找*/          // if ( *(t - 1) != '\\' ) {            // break; // 这次的符号不是转义,则表示找到真正字符串末尾了          // }        // }        off = tmp - p+1/* 计算本次拷贝长度 */;        if (off > 1) {          strncpy(s, p, off);          p += off - 1; // 外面有一个p++,所以这里少加一个          s += off;        }      break;      case '/':        switch ( *(p + 1) ) {          case '*': // 组成 /*            if (NULL != (t = strstr(p + 1, "*/"))) {              p = t + 1; /* 这里把指针指向 /* 结束标记 */            }          break;          case '/':  //  组成 //            for (tmp = p - 1; 0 != isspace(*tmp); tmp--) {            } // /* 这里的循环用于去掉空行注释            s -= p - tmp - 1; // s倒退到上一个非空白字符            *s++ = '\n'; /* //是单行注释,因此必须有一个换行 */            while (*p != '\n' && *p != '\r') {              p++;//  p指针移到下一个回车换行            }          break;          default: // 没有匹配注释字符            *s++ = *p;          break;        }      break;      default: // 没有匹配字符则逐个写        *s++ = *p;      break;    }  }  *s = '\0'; // 写结束标记}/*** 因为一个源码文件最大也就几M* 所以全部读到内存处理,绰绰有余的* 这里是多行注释,去掉后会有一个回车* 及多行注释缩短为一行**/int main(int argc, char *argv[]){  if (argc != 2) { /* 传递参数不正确 */    printf("Usage : %s file.c\n", argv[0]);    return -1;  }  const char *filename = argv[1]; // 得到文件名  struct stat statbuff;  /* 得到文件信息结构体 */  if(stat(filename, &statbuff) < 0){    return -1; // 获取文件大小失败  }  off_t filesize = statbuff.st_size; // 缓存文件大小  char *fileBuff = (char *)malloc(sizeof(char) * filesize);  int fd = open(filename, O_RDONLY);  if (-1 == fd) {    printf("open %s : %s\n", filename, strerror(errno));    return errno;  }  ssize_t n = read(fd, fileBuff, filesize);  if (n <= 0) { // 读取错误或空文件,直接关闭文件并退出    close(fd);    return -1;  }  *(fileBuff + n) = '\0'; /* 加上结束符 */  remove_comment(/* 直接把参数分成2半咯 */fileBuff); // 去除注释  printf("%s\n", fileBuff); /* 打印结果 */  close(fd);  return 0;}

4.下面演示一下功能,将上面的文件保存为main.c,执行
gcc main.c && .\a.exe main.c

#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <fcntl.h>#include <sys/stat.h>void remove_comment(char *buf){  size_t off;  char *s, *p, *t, *tmp;  char *sss="adas\"d/**/\"*a\"//s/**/d*/";  for (s = p = buf; *p != '\0'; p++) {    switch(*p) {      case '"':      case '\'':        for (tmp = p + 1; *tmp != *p; tmp++) {          if (*tmp == '\\') {            tmp++;          }        }        off = tmp - p+1;        if (off > 1) {          strncpy(s, p, off);          p += off - 1;          s += off;        }      break;      case '/':        switch ( *(p + 1) ) {          case '*':            if (NULL != (t = strstr(p + 1, "*/"))) {              p = t + 1;            }          break;          case '/':            for (tmp = p - 1; 0 != isspace(*tmp); tmp--) {            }            s -= p - tmp - 1;            *s++ = '\n';            while (*p != '\n' && *p != '\r') {              p++;            }          break;          default:            *s++ = *p;          break;        }      break;      default:        *s++ = *p;      break;    }  }  *s = '\0';}int main(int argc, char *argv[]){  if (argc != 2) {    printf("Usage : %s file.c\n", argv[0]);    return -1;  }  const char *filename = argv[1];  struct stat statbuff;  if(stat(filename, &statbuff) < 0){    return -1;  }  off_t filesize = statbuff.st_size;  char *fileBuff = (char *)malloc(sizeof(char) * filesize);  int fd = open(filename, O_RDONLY);  if (-1 == fd) {    printf("open %s : %s\n", filename, strerror(errno));    return errno;  }  ssize_t n = read(fd, fileBuff, filesize);  if (n <= 0) {    close(fd);    return -1;  }  *(fileBuff + n) = '\0';  remove_comment(fileBuff);  printf("%s\n", fileBuff);  close(fd);  return 0;}