注:添加了在行注释里面包含换行符'\'的情况,以及在字符串中包含包含"\\""的情况,该转义反斜杠而不是双引号。
#include <iostream>
//#include <string.h>
//#include <stdlib.h>
//#include <stdio.h>
#include <fcntl.h>
#include <io.h>
using namespace std;
//例5.1.1
// int i = 1;
// void main()
// {
// int i = i; //i是一个未定义值
// int j=i;
// }
//例5.2.2
// void main()
// {
// int b=3;
// int arr[] = {6,7,8,9,10};
// int *ptr = arr;
// *(ptr++) += 123;
// printf("%d,%d\n",*ptr,*(++ptr)); //输出结果为8,8
// }
//例5.4.2
// int main()
// {
// unsigned int a = 0xfffffff7;
// unsigned char i = (unsigned char)a;
// char *b = (char*)&a;
// printf("x,x\n",i,*b);
// }
//例5.5.1
// int main()
// {
// unsigned char a = 0xA5;
// unsigned char b = ~a>>4+1;
//cout<<b;
// printf("b = %d\n",b); //输出结果不是2,而是250
// return 0;
//}
//例5.8
void remove_comment(char *buf,size_t size)
{
char *p,*end,c; //p--动态移动的字符指针,end--指向文件末尾的字符指针,c--存储每一个p指向的字符
char *sq_start,*dq_start; //sq_start--单引号(single quotation)开始位置,dq_start--双引号(double quotation)开始位置
char *lc_start,*bc_start; //lc_start--//(行注释line comment)开始位置,bc_start-- //test
p=buf;
end = p + size;
sq_start = NULL;dq_start = NULL;lc_start = NULL;bc_start = NULL;
while(p < end){
c = *p;
switch (c){
case '\'': //单引号 由于使用了双引号,故需要使用单引号,比如:char c = '\"';若没有单引号,则该双引号至下一个双引号之间的部分均认为是代码
if(dq_start || lc_start || bc_start){
p++;
continue;
}
if(sq_start == NULL){
sq_start = p++;
}else{
len = p++ - sq_start;
if(len == 2 && *(sq_start + 1) == '\\') //忽略字符中的单引号
continue;
sq_start = NULL;
}
break;
case '\"': //双引号 比如:char filename1[100] = "//abcde/*";
if(sq_start || lc_start || bc_start){
p++;
continue;
}
if(dq_start == NULL)
dq_start = p++;
else{
if (*(p - 2) == '\\' && *(p++-1) == '\\'){ //比如在字符串中转义反斜杠字符,比如:char filename2[100] = "\\";
dq_start = NULL;
continue;
}
if(*(p++ - 1) == '\\')
continue;
dq_start = NULL;
}
break;
case '/':
if(sq_start || dq_start || lc_start || bc_start){
p++;
continue;
}
c = *(p+1);
if(c == '/'){
lc_start = p;
p += 2;
}else if(c == '*'){
bc_start = p;
p += 2;
}else{
p++;
}
break;
case '*':
if(sq_start || dq_start || lc_start || bc_start == NULL){
p++;
continue;
}
if(*(p+1) != '/'){
p++;
continue;
}
p += 2;
memset(bc_start,' ',p - bc_start);
bc_start = NULL;
break;
case '\n': //换行符
if(lc_start == NULL){
p++;
continue;
}
c = *(p-1);
if(*(p-1) == '\r' && *(p-2) == '\\' || *(p-1) == '\\')
memset(lc_start,' ',(c == '\r' ? (p++ - 1) : p++) - lc_start);
else{
memset(lc_start,' ',(c == '\r' ? (p++ - 1) : p++) - lc_start);
lc_start = NULL;
}
// memset(lc_start,' ',(c == '\r' ? (p++ - 1) : p++) - lc_start);
break;
default:
p++;
break;
}
}
if(lc_start) //删除最后一行的注释(所在注释行为最后一行时)
memset(lc_start,' ',p - lc_start);
}
int main(){
int fd,n;
char buf[10240];
fd = open("main.cpp",O_RDONLY,0); //test 其中main.cpp即该代码
if(fd == -1)
return -1;
n = read(fd,buf,sizeof(buf));
if(n == -1 || n == 0){
close(fd);
return -1;
}
remove_comment(buf,n);
*(buf + n) = '\0';
printf("%s\n",buf);
close(fd);
FILE *fp = fopen("save.txt","w");
fwrite(buf,sizeof(char),n+1,fp);
fclose(fp);
return 0;
}