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;
}

最新文章

  1. iOS中数据传值的几种方式
  2. codeforces 425C Sereja and Two Sequences(DP)
  3. [安卓]应用程序资源(App Resources)
  4. php的header()函数之设置content-type
  5. 【Python】django权限管理
  6. 游戏模块分析总结(2)之UI、操作篇
  7. PHP多线程的实现方法详解
  8. 【转】jqGrid学习之参数
  9. Azure Machine Learning
  10. 外键 Foreign keys
  11. 使用Sphinx为你的python模块自动生成文档
  12. Rust 阴阳谜题,及纯基于代码的分析与化简
  13. 【转】如何解决使用keil下载或者调试程序是提示的“Invalid ROM Table”信息!
  14. Android应用--QR的生成(二维码)
  15. .NET基础 (12)时间的操作System.DateTime
  16. Struts+HIbernate+Spring
  17. gin入门
  18. Java 基础(8)——流程控制
  19. TCP/IP五层模型详解
  20. Sublime Theme

热门文章

  1. 循环删除list的方法
  2. linux定时删除过期文件
  3. firewalld 防火墙
  4. FTL指令常用标签及语法
  5. C#开发PACS医学影像三维重建(一):使用VTK重建3D影像
  6. 在VS2019使用MASM编写汇编程序
  7. Spark Extracting,transforming,selecting features
  8. PHP正则表达式核心技术完全详解 第2节
  9. Mac Catalina 下 gdb codesign问题解决
  10. Spring Boot第二弹,配置文件怎么造?