#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/dir.h>
#include <map>
#include <string>
#include <fstream>
using namespace std;
#define NULLCHAR 32 //ascii字符的32表示空字符
//删除注释.path:文件路径全名
void delComments(const char *path);
//判断是否为目录.path:文件路径全名
bool isDir(const char* path);
//删除文件夹下所有.c, cpp, .h的注释
void delComInDir(const char *path);
//删除文件夹下所有.c, cpp, .h的注释,这是递归方法
void delComInDir(const char *path, int recursive);
//取文件名的后缀名
const char *getSuffix(const char *path);
//取子串
char* substr(const char*str, unsigned long start, unsigned long end);
//删除注释类型
namespace CommentType
{
//删除"特定函数".funStr:函数名称
void delFun(const char *funStr, unsigned char *buffer, unsigned long size);
//删除"/**/"型注释
void delMuliCom(unsigned char *buffer, unsigned long size);
//删除"//"型等但行注释
void delSigleCom(const char *comStr, unsigned char *buffer, unsigned long size);
}
int main(int argc, const char * argv[])
{
delComInDir("/Users/zctech/Desktop/test");
//delComInDir("/Users/zctech/Downloads/temp/hjsg/Classes/network/websocket");
printf("操作完成");
return 0;
}
//删除注释.path:文件名
void delComments(const char *path)
{
int fd = open(path, O_RDWR);
//获取文件大小
struct stat sb;
fstat(fd, &sb);
unsigned char *start = (unsigned char *)mmap(NULL, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(start == MAP_FAILED) /* 判断是否映射成功 */
{
printf("映射失败,文件过大或者没有权限");
return;
}
CommentType::delSigleCom("//", start, sb.st_size);
CommentType::delFun("CCLog", start, sb.st_size);
CommentType::delFun("CCLOG", start, sb.st_size);
CommentType::delSigleCom("#pragma", start, sb.st_size);
CommentType::delFun("zctech::ZCLOGI", start, sb.st_size);
CommentType::delFun("ZCLOGI", start, sb.st_size);
close(fd);
munmap(start, sb.st_size); /* 解除映射 */
}
//判断是否为目录.path:文件路径全名
bool isDir(const char* path)
{
struct stat st;
lstat(path, &st);
return 0 != S_ISDIR(st.st_mode);
}
//删除文件夹下所有.c, cpp, .h的注释
void delComInDir(const char *path)
{
unsigned long len;
char temp[1024 * 1024];
//去掉末尾的'/'
len = strlen(path);
strcpy(temp, path);
if(temp[len - 1] == '/') temp[len -1] = '\0';
if(isDir(temp))
{
//处理目录
int recursive = 1;
delComInDir(temp, recursive);
}
else //输出文件
{
//找出.h和.cpp文件
if(0 == strcmp("h", getSuffix(temp)) || 0 == strcmp("cpp", getSuffix(temp)) || 0 == strcmp("c", getSuffix(temp)))
{
printf("%s\n", temp);
delComments(temp);
}
}
}
//遍历文件夹de递归函数
void delComInDir(const char *path, int recursive)
{
DIR *pdir;
struct dirent *pdirent;
char temp[1024 * 1024];
pdir = opendir(path);
if(pdir)
{
while((pdirent = readdir(pdir)))
{
//跳过"."和".."
if(strcmp(pdirent->d_name, ".") == 0
|| strcmp(pdirent->d_name, "..") == 0)
continue;
sprintf(temp, "%s/%s", path, pdirent->d_name);
//当temp为目录并且recursive为1的时候递归处理子目录
if(isDir(temp) && recursive)
{
delComInDir(temp, recursive);
}
else
{
//找出.h和.cpp文件
if(0 == strcmp("h", getSuffix(temp)) || 0 == strcmp("cpp", getSuffix(temp)) || 0 == strcmp("c", getSuffix(temp)))
{
printf("%s\n", temp);
delComments(temp);
}
}
}
}
else
{
printf("opendir error:%s\n", path);
}
closedir(pdir);
}
//求子串
char* substr(const char*str, unsigned long start, unsigned long end)
{
unsigned long n = end - start;
static char stbuf[1024 * 1024];
strncpy(stbuf, str + start, n);
stbuf[n] = 0; //字串最后加上0
return stbuf;
}
//取文件名的后缀名
const char *getSuffix(const char *path)
{
char *ptr;
long pos;
ptr = strrchr(path, '.'); //最后一个出现c的位置
if(NULL == ptr)
{
return "";
}
pos = ptr - path; //用指针相减 求得索引
return substr(path, pos + 1, strlen(path));
}
//删除"//"型注释
void CommentType::delSigleCom(const char *comStr, unsigned char *buffer, unsigned long size)
{
//如果要删除但行注释先要删除多行注释/**/
CommentType::delMuliCom(buffer, size);
unsigned long i = 0;
bool isCom = false;
bool isStr = false;
while (i < size)
{
if(!isStr && 0 == strcmp(comStr, substr((char *)buffer, i, i + strlen(comStr))))
{
isCom = true;
}
else if(!isStr && isCom && '\n' == *(buffer + i))
{
isCom = false;
}
else if(!isCom && !isStr && '\"' == *(buffer + i) && '\\' != *(buffer + i - 1))
{
isStr = true;
}
else if(!isCom && isStr && '\"' == *(buffer + i) && '\\' != *(buffer + i - 1))
{
isStr = false;
}
if('\n' == *(buffer + i))
{isStr = false;}
//移除注释
if (isCom && !isStr)
{
*(buffer + i) = 32;
}
i++;
}
}
//删除"/**/"型注释
void CommentType::delMuliCom(unsigned char *buffer, unsigned long size)
{
//判断是否为 【/**/】 型注释, 注意当是字符串的时候不替换
unsigned long i = 0;
bool isCom = false;
bool isStr = false;
while (i < size)
{
if(!isStr && '/' == *(buffer + i) && '*' == *(buffer + i + 1))
{
isCom = true;
}
else if(!isStr && isCom && '*' == *(buffer + i) && '/' == *(buffer + i + 1))
{
isCom = false;
*(buffer + i) = *(buffer + i + 1) = 32;
}
else if(!isCom && !isStr && '\"' == *(buffer + i) && '\\' != *(buffer + i - 1))
{
isStr = true;
}
else if(!isCom && isStr && '\"' == *(buffer + i) && '\\' != *(buffer + i - 1))
{
isStr = false;
}
if('\n' == *(buffer + i))
{isStr = false;}
//移除注释
if (isCom && !isStr)
{
*(buffer + i) = 32;
}
i++;
}
}
//删除"特定函数".funStr:函数名称
void CommentType::delFun(const char *funStr, unsigned char *buffer, unsigned long size)
{
unsigned long i = 0;
bool isStr = false, isFun = false;
int left = 0, right = 0; //左右括号
while (i < size)
{
if(!isStr && 0 == strcmp(funStr, substr((char *)buffer, i, i + strlen(funStr)))
)
{
isFun = true;
}
else if(!isFun && !isStr && '\"' == *(buffer + i))
{
isStr = true;
}
else if(!isFun && isStr && '\"' == *(buffer + i))
{
isStr = false;
}
if(isFun && '(' == *(buffer + i))
{
left++;
}
else if(isFun && ')' == *(buffer + i))
{
right++;
if(left == right)
{
*(buffer + i) = NULLCHAR;
isFun = false;
unsigned long j = i + 1;
while (' ' == *(buffer + j) || ';' == *(buffer + j))
{
*(buffer + j) = NULLCHAR;
j++;
}
}
}
//移除注释
if (isFun && !isStr)
{
*(buffer + i) = NULLCHAR;
}
i++;
}
}
c语言超强删除注释的函数(linux、mac)
最新推荐文章于 2022-10-12 20:15:00 发布